在Excel VBA或VSTO 2005中遍历所有单元格

24

我需要简单地遍历Excel电子表格中的所有单元格并检查单元格中的值。这些单元格可能包含文本、数字或为空。我对“范围”的概念不是很熟悉/不太舒服。因此,任何示例代码都将不胜感激。(我尝试过在谷歌上搜索,但找到的代码片段并没有完全满足我的需求)

谢谢。

9个回答

64

如果您只需要查看使用中的单元格,可以使用:

sub IterateCells()

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

End Sub

这将命中从A1到最后一个有数据的单元格范围内的所有内容(最右下角的单元格)。


2
哇...比worksheet.cells好多了,后者会让我的系统崩溃! - Mr Purple
是的,这是许多要迭代的单元格。 - cori

7
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

我在http://www.java2s.com/Code/VBA-Excel-Access-Word/Excel/Checksvaluesinarange10rowsby5columns.htm 上找到了这个片段。它似乎非常有用,可以演示按顺序检查单元格中的值的方法。
把它看作一种二维数组,并应用相同的逻辑来循环遍历单元格。

4
循环遍历范围内的每个单元格的代码效率非常低下。将范围读入数组中,对数组进行检查/更改,然后将数组写回到范围中。让我们都同意不再使用这段代码,也许它就会被淘汰掉。 - JimmyPena

5

如果你只是查看单元格的值,你可以将这些值存储在一个变量类型为数组的变量中。似乎使用数组来获取元素的值比与Excel进行交互要快得多,因此,与反复获取单个单元格相比,使用包含所有单元格值的数组可能会在性能上产生一些差异。

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

然后,您可以通过检查ValArray(row, column)来获取单元格的值。

1
完全同意!我刚试了一下我的第一次运行,仅有几千个单元格,居然花费了超过30秒,这太奇怪了! - Ryan Liang

4
您可以使用For Each循环遍历已定义范围内的所有单元格。
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

2

如果您使用VB或C#应用程序,一种方法是使用Office Interop。这取决于您使用的Excel版本。

对于Excel 2003,此MSDN文章是一个很好的起点。 从Visual Studio 2005开发人员的角度了解Excel对象模型

您基本上需要执行以下操作:

  • 启动Excel应用程序。
  • 打开Excel工作簿。
  • 通过名称或索引检索工作簿中的工作表。
  • 迭代通过作为范围检索的工作表中的所有单元格。
  • 以下是最后一步的代码段示例(未经测试)。

    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.
        }
    }

如果您使用的是Excel 2007,可以查看这篇MSDN参考文献


1

你可以基本上循环遍历一个范围

获取一个工作表

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

获取您感兴趣的范围。如果您确实想要检查每个单元格,请使用Excel的限制。

Excel 2007的“大网格”将每个工作表的最大行数从65,536增加到超过1百万,并且列数从256(IV)增加到16,384(XFD)。请参阅http://msdn.microsoft.com/en-us/library/aa730921.aspx#Office2007excelPerf_BigGridIncreasedLimitsExcel

然后循环遍历该范围。

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

        string myValue;

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

1

有几种方法可以实现这个目标,每种方法都有优缺点;首先,您需要一个工作表对象的实例,如果您只想要用户正在查看的工作表,则可以使用Application.ActiveSheet。

Worksheet对象有三个属性可用于访问单元格数据(Cells、Rows、Columns),以及一个可用于获取一块单元格数据的方法(get_Range)。

范围可以调整大小等,但您可能需要使用上述提到的属性来找出数据边界在哪里。当您处理大量数据时,使用范围的优势变得明显,因为VSTO插件托管在Excel应用程序本身的边界之外,因此所有对Excel的调用都必须通过具有开销的层传递;获取范围允许您在一个调用中获取/设置所有所需的数据,这可以带来巨大的性能优势,但需要您使用显式细节而不是迭代每个条目。

这篇MSDN论坛帖子展示了一个VB.Net开发人员询问如何将范围的结果作为数组获取的问题


0
在Excel VBA中,这个函数将会给你任何工作表中任意单元格的内容。
Function getCellContent(Byref ws As Worksheet, ByVal rowindex As Integer, ByVal colindex As Integer) as String
    getCellContent = CStr(ws.Cells(rowindex, colindex))
End Function

所以,如果你想要检查单元格的值,只需要将该函数放在一个循环里面,给它提供你想要的工作表参照、行索引和列索引即可。行索引和列索引都从1开始,意味着单元格A1将会是ws.Cells(1,1),以此类推。

0

我的VBA技能有点生疏,但这是我会做的一般想法。
最简单的方法是为每一列迭代一个循环:

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

看起来语法高亮不支持VBA,但希望这会有所帮助(至少给你一个开始的方向)。

  • Brisketeer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接