16

自 Excel 2010 以来,我在 Excel 中使用了很多表格。例如,我有一个包含 3 列的表“tabWorkers”:“ID”、“Firstname”、“Lastname”。

我已经发现我可以使用 [] 引用 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 这样的变量,但我想要正确的语法。我确信这是可能的,但只是没有真正记录(比如 [tabWorkers].Rows)

4

8 回答 8

19

我对引用表格的速记方法不是很熟悉。如果您没有得到答案,您可能会发现这个使用 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
于 2012-09-19T14:50:06.947 回答
8

试试这个:

Dim row as Range
For Each row in [tabWorkers[first name]].Rows
     MsgBox row.Value
Next
于 2013-09-20T15:39:02.597 回答
8

我也思考过这个问题,搜索了又搜索,没有找到一个很好的答案

终于今天一分钱掉了,我找到了一些我想分享的东西,以帮助那些有同样困扰我的问题的人。

简而言之,问题是:如何使用表格各部分的标准名称在 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[Colour]") 或 Range("Params[Height]") 等来引用名为 Params 的表,其中包含名为 Colour、Size 和 Height 的列。您不喜欢这样吗?:-)

这个发现真的让我迷上了 Tables。它们现在以可读和兼容的方式为我提供了 vba 和工作表之间的非常整洁的链接。

谢谢微软!

鲍勃·乔丹 B

于 2014-08-07T10:38:48.797 回答
3

我通常这样做

Dim rng as Range
Set rng = Application.Range("Tablename[Columnname]")

您只需要参考工作簿,因为表名在整个工作簿中是唯一的。但是,如果您在不同的打开工作簿中有相同名称的表,那么这将影响活动工作簿,而不是两者或后台中的一个。为防止发生这种情况,您应该调用表格所在的实际工作表的范围对象。

希望这将表明它可以按照我上面描述的方式完成:

例如,我在 Access 数据库中有一个方法,该方法将条件格式应用于 Excel 文档中的表格,我将使用CopyFromRecordSet.

其中有一个签名

Private Function HighlightBlankOrZeroColumn(RangeToFormat As Range, HighlightColor As Long)

我这样打电话

HighlightBlankOrZeroColumn ApXL.Range("Table1[" & SoucreRst.Fields(intCount).Name & "]"), BlankOrZeroColor

其中ApXL是 aNew Excel.Application并且SoucreRst是 ADO 记录集。

到那时,我已经通过调用这两种方法创建了我的 Recordset --> Range 一个表:

xlWSh.ListObjects.Add(xlSrcRange, xlWSh.UsedRange, , xlYes).Name = "Table1"
xlWSh.ListObjects("Table1").TableStyle = "TableStyleLight16"
于 2012-09-19T14:27:47.710 回答
3

更简洁,在 Excel 2007 中测试:

Dim row As Range
For Each row In [tabWorkers].Rows
    MsgBox Intersect (row,[tabWorkers[FirstName]]).Value
Next
于 2016-02-11T15:17:26.487 回答
0

谢谢道格!这有很大帮助。一个工作示例:

Dim row As Range
For Each row In [tabWorkers].Rows
    MsgBox (row.Columns(row.ListObject.ListColumns("Firstname").Index).Value)
Next
于 2012-09-20T07:49:41.910 回答
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
于 2017-09-01T00:43:09.667 回答
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

希望它可以帮助某人。

于 2020-01-29T07:19:22.147 回答