自Excel 2010以来,我在Excel中使用了很多表。 例如,我有一个包含3列的表“tabWorkers”:“ID”,“名字”,“姓氏”。
我已经发现我可以使用[]来引用VBA中的表。 例如:
Dim row As Range
For Each row In [tabWorkers].Rows
MsgBox (row.Columns(2).Value)
Next
这将为我提供每行的名字,但是我希望通过使用它的列名来使其更具动态性:
Dim row As Range
For Each row In [tabWorkers].Rows
MsgBox (row.Columns("Firstname").Value)
Next
当然我可以进行某种查找,将列索引'2'绑定到类似FirstnameIndex的var,但我想要正确的语法。我确信这是可能的但是没有真正记录(比如[tabWorkers] .Rows)
答案 0 :(得分:18)
我不太熟悉引用表格的简写方法。如果你没有得到答案,你可能会发现这个使用ListOject模型的简化方法很有用:
Sub ListTableColumnMembers()
Dim lo As Excel.ListObject
Dim ws As Excel.Worksheet
Dim lr As Excel.ListRow
Set ws = ThisWorkbook.Worksheets(2)
Set lo = ws.ListObjects("tabWorkers")
For Each lr In lo.ListRows
Debug.Print Intersect(lr.Range, lo.ListColumns("FirstName").Range).Value
Next lr
End Sub
答案 1 :(得分:8)
试试这个:
Dim row as Range
For Each row in [tabWorkers[first name]].Rows
MsgBox row.Value
Next
答案 2 :(得分:7)
我也在思考这个问题并搜索和搜索而没有找到一个非常好的答案
最后今天,便士掉了下来,我找到了一些我想分享的东西,以帮助那些追随我的同样问题的人。
简而言之,问题是:如何使用表的各部分的标准名称来引用vba中表的行。事实证明这很容易。您可以引用表的特定行并按其真实名称调用列,而无需重新定义任何其他变量。
构造如下:Range(" TableName [ColumnName]")(RowNumber)
其中TableName和ColumnName是Excelside中的标准表和列名,RowNumber是从1到Range的行号的简单整数索引(" Table1")。Rows.Count
对于名为Table1的两列表,其中包含名为ID和Data的列,您可以使用此构造循环遍历表元素
For Rw = 1 To Range("Table1").Rows.Count
MsgBox(Range("Table1[ID]")(Rw) & "has value" & Range("Table1[Data]")(Rw) )
Next Rw
这保持了与Excel中使用的结构非常相似的结构,并且不需要额外的命名。它非常易读!您还可以根据需要在该(Rw)部分之后附加适当的范围修饰符,例如.Text,.Value,.Formula等。
请注意,如果您有一个单行表(例如参数),或者希望引用较大表的第一行,则可以跳过(Rw)位并直接使用Range。因此,可以使用Range(" Params [Color]")或Range(" Params [Height]")等来引用名为Params的表,其中包含颜色,大小和高度的列。你不喜欢那样吗? : - )
这个发现真的让我迷上了桌子。现在,它们以可读和兼容的方式为我提供了vba与工作表之间非常整洁的链接。
谢谢微软!
Bob JordanB
答案 3 :(得分:3)
我通常会这样做
Dim rng as Range
Set rng = Application.Range("Tablename[Columnname]")
您只需要引用工作簿,因为表名在整个工作簿中是唯一的。但是,如果您在不同的打开工作簿中具有相同名称的表,那么这将影响活动工作簿,而不是两者或后台工作簿。为了防止这种情况,您应该调用表所在的实际工作表的范围对象。
希望这表明它可以按照我上面描述的方式完成:
例如,我在Access数据库中有一个方法,它将条件格式应用于我刚刚创建并使用CopyFromRecordSet
填充的Excel文档中的表。
其中有
的签名Private Function HighlightBlankOrZeroColumn(RangeToFormat As Range, HighlightColor As Long)
我打电话就是这样
HighlightBlankOrZeroColumn ApXL.Range("Table1[" & SoucreRst.Fields(intCount).Name & "]"), BlankOrZeroColor
其中ApXL
是New Excel.Application
,SoucreRst
是ADO记录集。
到那时我已经制作了我的Recordset - >通过调用这两个方法来对表进行排序:
xlWSh.ListObjects.Add(xlSrcRange, xlWSh.UsedRange, , xlYes).Name = "Table1"
xlWSh.ListObjects("Table1").TableStyle = "TableStyleLight16"
答案 4 :(得分:3)
更简洁,在Excel 2007中测试:
Dim row As Range
For Each row In [tabWorkers].Rows
MsgBox Intersect (row,[tabWorkers[FirstName]]).Value
Next
答案 5 :(得分:0)
Dim row As Range
For Each row In [tabWorkers].Rows
MsgBox (row.Columns(row.ListObject.ListColumns("Firstname").Index).Value)
Next
答案 6 :(得分:0)
这也是我的第一篇文章。 问题问题已经过了很长时间,但我希望无论如何都会有所帮助。
主要思想是让代码尽可能整洁。
Set selrange = Selection.EntireRow
For Each rrow In selrange.Rows
selrange.Parent.Parent.Names.Add "rrow", rrow
name = [table1[name] rrow].Text
age = [table1[age] rrow].Text
gender = [table1[gender] rrow].Text
Next
selrange.Parent.Parent.Names("rrow").Delete
答案 7 :(得分:0)
感谢对此线程的所有解答,并进行了一些其他研究,以下是我的代码版本。基本上,您在代码的前面定义了列,并在遍历各行时,为每行提取已定义列的值。
Sub xlTableLoop_namedColumns()
Dim lst As ListObject
Dim rw As ListRow
Dim colSubject As ListColumn
Dim colDate As ListColumn
Set lst = ActiveSheet.ListObjects("mlist") 'the name of Table
Set colSubject = lst.ListColumns("Subject") 'the name of column 1 in table header
Set colDate = lst.ListColumns("date") 'the name of column 2 in table header
For Each rw In lst.ListRows 'loop through all the rows
Debug.Print colSubject.DataBodyRange.Rows(rw.Index).Value 'get value of column 1
Debug.Print colDate.DataBodyRange.Rows(rw.Index).Value 'get value of column 2
Next
End Sub
希望它对某人有帮助。