Question

I need to simply go through all the cells in a Excel Spreadsheet and check the values in the cells. The cells may contain text, numbers or be blank. I am not very familiar / comfortable working with the concept of 'Range'. Therefore, any sample codes would be greatly appreciated. (I did try to google it, but the code snippets I found didn't quite do what I needed)

Thank you.

Was it helpful?

Solution

Sub CheckValues1()
    Dim rwIndex As Integer
    Dim colIndex As Integer
    For rwIndex = 1 To 10
            For colIndex = 1 To 5
                If Cells(rwIndex, colIndex).Value <> 0 Then _
                    Cells(rwIndex, colIndex).Value = 0
            Next colIndex
    Next rwIndex
End Sub

Found this snippet on http://www.java2s.com/Code/VBA-Excel-Access-Word/Excel/Checksvaluesinarange10rowsby5columns.htm It seems to be quite useful as a function to illustrate the means to check values in cells in an ordered fashion.

Just imagine it as being a 2d Array of sorts and apply the same logic to loop through cells.

OTHER TIPS

If you only need to look at the cells that are in use you can use:

sub IterateCells()

   For Each Cell in ActiveSheet.UsedRange.Cells
      'do some stuff
   Next

End Sub

that will hit everything in the range from A1 to the last cell with data (the bottom right-most cell)

If you're just looking at values of cells you can store the values in an array of variant type. It seems that getting the value of an element in an array can be much faster than interacting with Excel, so you can see some difference in performance using an array of all cell values compared to repeatedly getting single cells.

Dim ValArray as Variant
ValArray = Range("A1:IV" & Rows.Count).Value

Then you can get a cell value just by checking ValArray( row , column )

You can use a For Each to iterate through all the cells in a defined range.

Public Sub IterateThroughRange()

Dim wb As Workbook
Dim ws As Worksheet
Dim rng As Range
Dim cell As Range

Set wb = Application.Workbooks(1)
Set ws = wb.Sheets(1)
Set rng = ws.Range("A1", "C3")

For Each cell In rng.Cells
    cell.Value = cell.Address
Next cell

End Sub

For a VB or C# app, one way to do this is by using Office Interop. This depends on which version of Excel you're working with.

For Excel 2003, this MSDN article is a good place to start. Understanding the Excel Object Model from a Visual Studio 2005 Developer's Perspective

You'll basically need to do the following:

  • Start the Excel application.
  • Open the Excel workbook.
  • Retrieve the worksheet from the workbook by name or index.
  • Iterate through all the Cells in the worksheet which were retrieved as a range.
  • Sample (untested) code excerpt below for the last step.

    Excel.Range allCellsRng;
    string lowerRightCell = "IV65536";
    allCellsRng = ws.get_Range("A1", lowerRightCell).Cells;
    foreach (Range cell in allCellsRng)
    {
        if (null == cell.Value2 || isBlank(cell.Value2))
        {
          // Do something.
        }
        else if (isText(cell.Value2))
        {
          // Do something.
        }
        else if (isNumeric(cell.Value2))
        {
          // Do something.
        }
    }

For Excel 2007, try this MSDN reference.

There are several methods to accomplish this, each of which has advantages and disadvantages; First and foremost, you're going to need to have an instance of a Worksheet object, Application.ActiveSheet works if you just want the one the user is looking at.

The Worksheet object has three properties that can be used to access cell data (Cells, Rows, Columns) and a method that can be used to obtain a block of cell data, (get_Range).

Ranges can be resized and such, but you may need to use the properties mentioned above to find out where the boundaries of your data are. The advantage to a Range becomes apparent when you are working with large amounts of data because VSTO add-ins are hosted outside the boundaries of the Excel application itself, so all calls to Excel have to be passed through a layer with overhead; obtaining a Range allows you to get/set all of the data you want in one call which can have huge performance benefits, but it requires you to use explicit details rather than iterating through each entry.

This MSDN forum post shows a VB.Net developer asking a question about getting the results of a Range as an array

You basically can loop over a Range

Get a sheet

myWs = (Worksheet)MyWb.Worksheets[1];

Get the Range you're interested in If you really want to check every cell use Excel's limits

The Excel 2007 "Big Grid" increases the maximum number of rows per worksheet from 65,536 to over 1 million, and the number of columns from 256 (IV) to 16,384 (XFD). from here http://msdn.microsoft.com/en-us/library/aa730921.aspx#Office2007excelPerf_BigGridIncreasedLimitsExcel

and then loop over the range

        Range myBigRange = myWs.get_Range("A1", "A256");

        string myValue;

        foreach(Range myCell in myBigRange )
        {
            myValue = myCell.Value2.ToString();
        }

In Excel VBA, this function will give you the content of any cell in any worksheet.

Function getCellContent(Byref ws As Worksheet, ByVal rowindex As Integer, ByVal colindex As Integer) as String
    getCellContent = CStr(ws.Cells(rowindex, colindex))
End Function

So if you want to check the value of cells, just put the function in a loop, give it the reference to the worksheet you want and the row index and column index of the cell. Row index and column index both start from 1, meaning that cell A1 will be ws.Cells(1,1) and so on.

My VBA skills are a little rusty, but this is the general idea of what I'd do.
The easiest way to do this would be to iterate through a loop for every column:

public sub CellProcessing()
on error goto errHandler

    dim MAX_ROW as Integer   'how many rows in the spreadsheet
    dim i as Integer
    dim cols as String

    for i = 1 to MAX_ROW
        'perform checks on the cell here
        'access the cell with Range("A" & i) to get cell A1 where i = 1
    next i

exitHandler:
    exit sub
errHandler:
    msgbox "Error " & err.Number & ": " & err.Description
    resume exitHandler
end sub

it seems that the color syntax highlighting doesn't like vba, but hopefully this will help somewhat (at least give you a starting point to work from).

  • Brisketeer
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top