【问题标题】:Iterating through all the cells in Excel VBA or VSTO 2005遍历 Excel VBA 或 VSTO 2005 中的所有单元格
【发布时间】:2008-09-16 15:47:16
【问题描述】:

我需要简单地浏览 Excel 电子表格中的所有单元格并检查单元格中的值。单元格可能包含文本、数字或空白。我不太熟悉/不习惯使用“范围”的概念。因此,任何示例代码将不胜感激。 (我确实尝试过 google,但我发现的代码 sn-ps 并没有完全满足我的需要)

谢谢。

【问题讨论】:

    标签: vba excel vsto


    【解决方案1】:

    您可以使用 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】:

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

      sub IterateCells()
      
         For Each Cell in ActiveSheet.UsedRange.Cells
            'do some stuff
         Next
      
      End Sub
      

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

      【讨论】:

      • 哇...比让我的系统崩溃的 worksheet.cells 好多了!
      • 是的,这是一个需要迭代的整个单元格。
      【解决方案3】:
      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 上找到了这个 sn-p,它作为一个函数来说明以有序方式检查单元格中的值的方法似乎非常有用。

      想象一下它是一个二维数组,并应用相同的逻辑循环遍历单元格。

      【讨论】:

      • 循环遍历范围内每个单元格的代码效率极低。将范围读入数组,对数组进行检查/更改,然后将数组写回范围。让我们同意停止使用此代码,也许它会消失。
      【解决方案4】:

      如果您只是查看单元格的值,您可以将这些值存储在变体类型的数组中。似乎在数组中获取元素的值比与 Excel 交互要快得多,因此您可以看到使用包含所有单元格值的数组与重复获取单个单元格相比在性能方面存在一些差异。

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

      然后你可以通过检查 ValArray( row , column ) 得到一个单元格值

      【讨论】:

      • 完全同意!我刚刚尝试了我的第一次运行,只运行了几千个单元,花了 30 多秒,这很奇怪!
      【解决方案5】:

      对于 VB 或 C# 应用程序,一种方法是使用 Office 互操作。这取决于您使用的 Excel 版本。

      对于 Excel 2003,这篇 MSDN 文章是一个很好的起点。 Understanding the Excel Object Model from a Visual Studio 2005 Developer's Perspective

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

      • 启动 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,请尝试 this MSDN reference

      【讨论】:

        【解决方案6】:

        有几种方法可以做到这一点,每种方法都有优点和缺点;首先,您需要有一个 Worksheet 对象的实例,如果您只想要用户正在查看的对象,Application.ActiveSheet 就可以工作。

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

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

        This MSDN forum post 显示 VB.Net 开发人员询问有关将 Range 的结果作为数组获取的问题

        【讨论】:

          【解决方案7】:

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

          拿一张纸

          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();
                  }
          

          【讨论】:

            【解决方案8】:

            在 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) 等等。

            【讨论】:

              【解决方案9】:

              我的 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,但希望这会有所帮助(至少给你一个工作的起点)。

              • 胸肉手

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2017-05-14
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多