首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在VBA中迭代excel工作表的所有行

如何在VBA中迭代excel工作表的所有行
EN

Stack Overflow用户
提问于 2016-04-24 20:26:27
回答 3查看 5.1K关注 0票数 1

我有以下代码(此代码位于Access VBA中,该VBA试图读取excel文件,并在检查后可能导入它):

代码语言:javascript
复制
Set ExcelApp = CreateObject("Excel.application")
Set Workbook = ExcelApp.Workbooks.Open(FileName)
Set Worksheet = Workbook.Worksheets(1)

现在,我想迭代excel工作表的所有行。我想要这样的东西:

代码语言:javascript
复制
for each row in Worksheet.rows
      ProcessARow(row)
next row

哪里

代码语言:javascript
复制
function ProcessARow(row as ???? )
   ' process a row
   ' how Should I define the function
   ' how can I access each cell in the row
   ' Is there any way that I can understand how many cell with data exist in the row

end function

我的问题:

  1. 如何定义它在具有数据的所有行上正确迭代的每一段代码?
  2. 如何正确定义ProcessARow
  3. 如何获取行中每个单元格的值。
  4. 如何找到一行中有多少个有数据的单元格?
  5. 有没有办法检测到每个单元格的数据类型是什么?

编辑1

该链接解决了问题:

代码语言:javascript
复制
How to define the for each code that it iterate correctly on all rows that has data? 

但其他问题呢?

例如,如何正确定义ProcessARow?

EN

回答 3

Stack Overflow用户

发布于 2016-04-24 20:40:08

如果需要行中的值,则需要使用“value”属性,并在执行循环之后获取每个值

代码语言:javascript
复制
for each row in Worksheet.rows
      Values=row.Value
      For each cell in Values
          ValueCell=cell
      next cell
next row
票数 0
EN

Stack Overflow用户

发布于 2016-04-24 21:09:50

不幸的是,你的问题是非常广泛的,但是我相信下面的子程序可以向你展示一些方法来实现你想要的。关于哪个数据类型,每个单元格更复杂,因为它取决于您希望比较它的数据类型,但是,我已经包含了一些希望有所帮助的内容。

代码语言:javascript
复制
sub hopefullyuseful()
    dim ws as worksheet
    dim rng as Range
    dim strlc as string
    dim rc as long, i as long
    dim lc as long, j as long
    dim celltoprocess as range
    set ws = activeworkbook.sheets(activesheet.name)
    strlc = ws.cells.specialcells(xlcelltypeLastCell).address
    set rng = ws.range("A1:" & lc)

    rc = rng.rows.count()
    debug.print "Number of rows: " & rc

    lc = rng.columns.count()
    debug.print "Number of columns: " & lc
    '
    'method 1 looping through the cells'
    for i = 1 to rc
        for j = 1 to lc
            set celltoprocess = ws.cells(i,j)
            'this gives you a cell object at the coordinates of (i,j)'
            '[PROCESS HERE]'
            debug.print celltoprocess.address & "  is  celltype: " & CellType(celltoprocess)
            'here you can do any processing you would like on the individual cell if needed however this is not the best method'
            set celltoprocess = nothing
        next j
    next i
    'method 2 looping through the cells using a for each loop'
    for each celltoprocess in rng.cells
        debug.print celltoprocess.address & "  is  " & CellType(celltoprocess)
    next celltoprocess

    'if you just need the data in the cells and not the actual cell objects'
    arrOfCellData = rng.value

    'to access the data'
    for i = lbound(arrOfCellData,1) to ubound(arrOfCellData,1)
        'i = row'
        for j = lbound(arrOfCellData,2) to ubound(arrOfCellData,2)
            'j = columns'
            debug.print "TYPE: "  & typename(arrOfCellData(i,j))  & "   character count:" & len(arrOfCellData(i,j))

        next j
    next i
    set rng=nothing
    set celltoprocess = nothing
    set ws = nothing
end sub

Function CellType(byref Rng as range) as string
    Select Case True
        Case IsEmpty(Rng)
            CellType = "Blank"
        Case WorksheetFunction.IsText(Rng)
            CellType = "Text"
        Case WorksheetFunction.IsLogical(Rng)
            CellType = "Logical"
        Case WorksheetFunction.IsErr(Rng)
            CellType = "Error"
        Case IsDate(Rng)
            CellType = "Date"
        Case InStr(1, Rng.Text, ":") <> 0
            CellType = "Time"
        Case IsNumeric(Rng)
            CellType = "Value"
    End Select
end function

sub processRow(byref rngRow as range)
    dim c as range
    'it is unclear what you want to do with the row however... if you want
    'to do something to cells in the row this is how you access them
    'individually

   for each c in rngRow.cells
        debug.print "Cell " & c.address & " is in Column " & c.column & " and Row " & c.row & " has the value of " & c.value
   next c 
   set c = nothing
   set rngRow = nothing

出口潜艇

如果你想要回答你的其他问题,你必须对你想要完成的事情更加具体。

票数 0
EN

Stack Overflow用户

发布于 2016-04-24 22:13:25

虽然我喜欢@krazynhazy提供的解决方案,但我相信下面的解决方案可能更短,更接近您的要求。不过,我还是会使用Krazynhazy提供的CellType函数,而不是下面代码中我目前拥有的所有Iif

代码语言:javascript
复制
Option Explicit

Sub AllNonEmptyCells()

Dim rngRow As Range
Dim rngCell As Range
Dim wksItem As Worksheet

Set wksItem = ThisWorkbook.Worksheets(1)

On Error GoTo EmptySheet
For Each rngRow In wksItem.Cells.SpecialCells(xlCellTypeConstants).EntireRow.Rows
    Call ProcessARow(wksItem, rngRow.Row)
Next rngRow

Exit Sub

EmptySheet:
    MsgBox "Sheet is empty." & Chr(10) & "Aborting!"
    Exit Sub

End Sub

Sub ProcessARow(wksItem As Worksheet, lngRow As Long)

Dim rngCell As Range

Debug.Print "Cells to process in row " & lngRow & ": " & wksItem.Range(wksItem.Cells(lngRow, 1), wksItem.Cells(lngRow, wksItem.Columns.Count)).SpecialCells(xlCellTypeConstants).Count
For Each rngCell In wksItem.Range(wksItem.Cells(lngRow, 1), wksItem.Cells(lngRow, wksItem.Columns.Count)).SpecialCells(xlCellTypeConstants)
    Debug.Print "Row: " & lngRow, _
                "Column: " & rngCell.Column, _
                "Value: " & rngCell.Value2, _
                IIf(Left(rngCell.Formula, 1) = "=", "Formula", IIf(IsDate(rngCell.Value), "Date", IIf(IsNumeric(rngCell.Value2), "Number", "Text")))
Next rngCell

End Sub

注意,您必须调用sub来调用一行,还必须包括应在其中处理行的工作表。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36828541

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档