VBA 中有没有办法添加 ListRow object 并按名称指定列?
Is there a way in VBA to add a ListRow object and specify the columns by name?
我有一个 table 像这样的“名字”
Name
Value
Pete
5
Hugo
1
并想添加新的数据点,比方说“Malcolm,9”。
我可以这样做:
Sub addName()
Dim tbl as Listobject: Set tbl = Range("Names").ListObject
With tbl.ListRows.Add
.Range(1) = "Malcolm"
.Range(2) = 9
End With
End Sub
为了灵活起见,更改列顺序,插入列等,我想这样做:
Sub addName()
Dim tbl as Listobject: Set tbl = Range("Names").ListObject
With tbl.ListRows.Add
.Range("Name") = "Malcolm"
.Range("Value") = 9
End With
End Sub
在 VBA 中有没有办法轻松实现这一点?有一种解决方法,您首先检查 table header,然后查找列名的位置。但这太乏味了。
希望这个不那么乏味的解决方法能够解决问题。您需要再插入两行。
Sub addName3()
Dim tbl As ListObject
Dim clm1 As Integer
Dim clm2 As Integer
Set tbl = Range("Names").ListObject
clm1 = tbl.ListColumns("Name").Index
clm2 = tbl.ListColumns("Value").Index
With tbl.ListRows.Add
.Range(clm1) = "Malcolm"
.Range(clm2) = 9
End With
End Sub
据我所知,没有内置的解决方案。
您当然可以创建自己的助手:
Sub Main()
Dim row as object: set row = CreateDict("Name", "Malcolm, "Age", 20)
row("height") = "5'7"
'later
Call addRow(myListObject, row)
End Sub
Function addRow(Byval lo as ListObject, ByVal oRow as object) as Boolean
On Error GoTo ErrorOccurred
Dim keys as variant: Keys = oRow.keys()
Dim v() as variant: Redim v(1 to 1, 1 to lo.listcolumns.count)
Dim iKey as long
For iKey = 0 to ubound(keys)
Dim sKey as string: sKey = keys(iKey)
On Error GoTo lcDoesntExist
v(1,lo.listcolumns(sKey).index) = oRow(sKey)
On Error GoTo 0
lcDoesntExist:
next
lo.ListRows.Add.Value = v
ErrorOccurred:
End Function
Function CreateDict(ParamArray Params()) as Object
Dim o as object: set o = CreateObject("Scripting.Dictionary")
Dim i as long
For i = 0 to ubound(params) step 2
if isObject(params(i+1)) then
set o(params(i)) = params(i+1)
else
let o(params(i)) = params(i+1)
end if
next
set CreateDict = o
End Function
此代码未经测试,可能存在一些问题。
我有一个 table 像这样的“名字”
Name | Value |
---|---|
Pete | 5 |
Hugo | 1 |
并想添加新的数据点,比方说“Malcolm,9”。
我可以这样做:
Sub addName()
Dim tbl as Listobject: Set tbl = Range("Names").ListObject
With tbl.ListRows.Add
.Range(1) = "Malcolm"
.Range(2) = 9
End With
End Sub
为了灵活起见,更改列顺序,插入列等,我想这样做:
Sub addName()
Dim tbl as Listobject: Set tbl = Range("Names").ListObject
With tbl.ListRows.Add
.Range("Name") = "Malcolm"
.Range("Value") = 9
End With
End Sub
在 VBA 中有没有办法轻松实现这一点?有一种解决方法,您首先检查 table header,然后查找列名的位置。但这太乏味了。
希望这个不那么乏味的解决方法能够解决问题。您需要再插入两行。
Sub addName3()
Dim tbl As ListObject
Dim clm1 As Integer
Dim clm2 As Integer
Set tbl = Range("Names").ListObject
clm1 = tbl.ListColumns("Name").Index
clm2 = tbl.ListColumns("Value").Index
With tbl.ListRows.Add
.Range(clm1) = "Malcolm"
.Range(clm2) = 9
End With
End Sub
据我所知,没有内置的解决方案。
您当然可以创建自己的助手:
Sub Main()
Dim row as object: set row = CreateDict("Name", "Malcolm, "Age", 20)
row("height") = "5'7"
'later
Call addRow(myListObject, row)
End Sub
Function addRow(Byval lo as ListObject, ByVal oRow as object) as Boolean
On Error GoTo ErrorOccurred
Dim keys as variant: Keys = oRow.keys()
Dim v() as variant: Redim v(1 to 1, 1 to lo.listcolumns.count)
Dim iKey as long
For iKey = 0 to ubound(keys)
Dim sKey as string: sKey = keys(iKey)
On Error GoTo lcDoesntExist
v(1,lo.listcolumns(sKey).index) = oRow(sKey)
On Error GoTo 0
lcDoesntExist:
next
lo.ListRows.Add.Value = v
ErrorOccurred:
End Function
Function CreateDict(ParamArray Params()) as Object
Dim o as object: set o = CreateObject("Scripting.Dictionary")
Dim i as long
For i = 0 to ubound(params) step 2
if isObject(params(i+1)) then
set o(params(i)) = params(i+1)
else
let o(params(i)) = params(i+1)
end if
next
set CreateDict = o
End Function
此代码未经测试,可能存在一些问题。