我刚刚开始使用VBA for Excel。近十年前我在大学里使用过VB和Java,并且当时很有能力,但我基本上已经开始了。 (嗯,不喜欢骑自行车。)
我正在尝试理解构建范围的方法,该范围不仅仅声明为A1:J34或其他。我的谷歌搜索受到挑战,因为当搜索“范围”和表示我所寻求的内容的术语时,我得到的雪崩远比我需要的更高级,主要是甚至没有解决我需要的基本摘要信息的命中。 / p>
所以,这是它的基础知识: Mac上的Excel 2011。 工作表的数据从A到M,低至1309。 它是标题行的重复模式,后跟数据行。啊。似乎创建工作表的人更多地考虑从工作表打印而不是数据组织。我需要清理它,还有3个像它一样用在数据透视表中,而且在这个愚蠢的重复布局中它是无用的。
标题行如下: 姓氏,名字,然后10个日期单元格。 标题下的数据行当然是名称,然后是1或0表示出席。 每个标题下的名称从20到30个。然后它重复。日期每隔几套就会改变一次,从最后一组停止的地方开始。
我现在需要做的事情: 我试图通过添加以特定值开头的所有行(在A列中)将范围组合成范围变量。在我的情况下,值是字符串“姓氏”,所以我可以使用范围变量保存所有以“姓氏”开头的行中的所有单元格。然后,这将捕获需要采用日期格式的所有单元格。 (我这样做,所以我可以确保日期标题都是实际的日期格式 - 因为它们现在都不是日期格式,许多只是'一般'单元格。)
我的问题:
答案 0 :(得分:1)
这是一个工作示例,演示了如何查找“姓氏”行,构建包含所有这些行的范围对象,然后遍历该对象以搜索非日期值。通过将数据范围读入变量数组,然后在数组中搜索姓氏行和这些行中的“错误日期”,可以极大地加速代码。如果要检查的行数非常多,则尤其如此。
Sub DisjointRng()
Dim checkCol As String, checkPattern As String
Dim dateCols()
Dim lastCell As Range, usedRng As Range, checkRng As Range
Dim cell As Variant
Dim usedRow As Range, resultRng As Range, rngArea As Range
Dim i As Long, j As Long
checkCol = "A" 'column to check for "Last Name"
checkPattern = "Last*"
dateCols = Array(3, 5) 'columns to check for date formatting
With Worksheets("Sheet1")
'find the bottom right corner of data range; we determine the used range
'ourselves since the built-in UsedRange is sometimes out-of-synch
Set lastCell = .Cells(.Cells.Find(What:="*", SearchOrder:=xlRows, _
SearchDirection:=xlPrevious, LookIn:=xlFormulas).Row, _
.Cells.Find(What:="*", SearchOrder:=xlByColumns, _
SearchDirection:=xlPrevious, LookIn:=xlFormulas).Column)
Set usedRng = .Range("A1:" & lastCell.Address)
'the column of values in which to look for "Last Name"
Set checkRng = .Range(checkCol & "1:" & checkCol & usedRng.Rows.Count)
End With
'step down the column of values to check for last name & add
'add found rows to range object
For Each cell In checkRng
If cell.Value Like checkPattern Then
'create a range object for the row
Set usedRow = Intersect(cell.EntireRow, usedRng)
If resultRng Is Nothing Then
'set the first row with "Last Name"
Set resultRng = usedRow
Else
'add each additional found row to the result range object
Set resultRng = Union(resultRng, usedRow)
End If
End If
Next cell
For Each rngArea In resultRng.Areas
'if found rows are continguous, Excel consolidates them
'into single area, so need to loop through each of the rows in area
For i = 1 To rngArea.Rows.Count
For j = LBound(dateCols) To UBound(dateCols)
If Not IsDate(rngArea.Cells(i, dateCols(j))) Then
'do something
End If
Next j
Next i
Next rngArea
End Sub
答案 1 :(得分:0)
您可以使用Union
运算符,例如
Dim r As Range
Set r = Range("A1, A3, A10:A12")
或者
Set r = Union(Range("A1"), Range("A3"), Range("A10:A12"))
你可以像这样迭代这个范围
Dim cl as Range
For Each cl in r.Cells
' code cell cl
Next
或者
Dim ar as Range
For each ar in r.Areas
' code using contiguous range ar
For each cl in ar.Cells
' code using cell cl
Next
Next