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

时间:2016-04-24 20:26:28

标签: excel vba access-vba

我有这段代码(此代码在Access VBA中尝试读取excel文件并在检查后可能导入它):

Set ExcelApp = CreateObject("Excel.application")
Set Workbook = ExcelApp.Workbooks.Open(FileName)
Set Worksheet = Workbook.Worksheets(1)

现在我想遍历excel工作表的所有行。我想要这样的东西:

for each row in Worksheet.rows
      ProcessARow(row)
next row

,其中

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. 有什么方法可以检测每个单元格的数据类型是什么?
  6. 编辑1

    该链接解决了问题:

    How to define the for each code that it iterate correctly on all rows that has data? 
    

    但其他问题呢?

    例如,如何正确定义ProcessARow?

3 个答案:

答案 0 :(得分:0)

如果您需要行中的值,则需要使用“值”属性,然后执行一个循环以获取每个值

for each row in Worksheet.rows
      Values=row.Value
      For each cell in Values
          ValueCell=cell
      next cell
next row

答案 1 :(得分:0)

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

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

退出子

如果您希望其他问题得到解答,则必须更具体地说明您要完成的任务

答案 2 :(得分:0)

虽然我喜欢@krazynhazy提供的解决方案,但我相信以下解决方案可能会稍微缩短一些,并且更接近您的要求。尽管如此,我还是使用了Krazynhazy提供的CellType函数,而不是我目前在下面的代码中使用的Iif函数。

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来调用一行,还必须包括应该处理一行的工作表。