我有一个宏从另一个工作簿中的列中提取数据。源和目标工作簿都具有可变行数,并且其中任何一列中的列都可以随时移动,因此根据标题名称而不是列索引匹配列。
我遇到的问题是我的目标工作表中的标题行不断被宏覆盖并替换为源工作表中的标题名称。因此,例如,如果目标列被调用"供应商"我不希望它被名为"供应商"的源工作表列覆盖。我尝试过实现ListHeaderRows功能但没有成功,有人能告诉我这段代码有什么问题吗?
提示:标题行从第2行开始,而不是第1行。
Set g = target_sheet.Rows(2).Find(what:="Supplier", _
lookat:=xlWhole, LookIn:=xlValues)
If Not g Is Nothing Then
Set mainVendorCol = g.EntireColumn
lHeadersRows = mainVendorCol.ListHeaderRows
If lheaderrows > 0 Then
Set mainVendorCol = mainVendorCol.Resize(mainVendorCol.Rows.Count - lHeadersRows)
Set mainVendorCol = mainVendorCol.Offset(2)
End If
Set ran = mainVendorCol
For Each c In ran.Cells
id = c.EntireRow.Cells(3).Value
If Len(id) > 0 Then
r = Application.Match(id, srcIdCol, 0)
If Not IsError(r) Then
c.Value = Application.Index(srcVendorCol, r, 1)
Else
c.Value = "PROJECT NOT FOUND"
End If
End If
Next c
End Sub
答案 0 :(得分:0)
我是这样做的。一开始可能看起来有点长,但是一旦设置完成,维护很少,你可以在所有项目中使用它。
我有一个名为cColumn的类模块:
Option Explicit
Private msHeader As String
Private miNumber As Integer
Public Property Get Header() As String
Header = msHeader
End Property
Public Property Let Header(ByVal sHeader As String)
msHeader = sHeader
End Property
Public Property Get Number() As Integer
Number = miNumber
End Property
Public Property Let Number(ByVal iNumber As Integer)
miNumber = iNumber
End Property
我在procdure中实例化这个类:
Dim colMainInfoColumns As Collection
Dim avarMainInfoColumnsToFind() As Variant
'this is a list of columns I want to find, you could also use an array:
avarMainInfoColumnsToFind = ThisWorkbook.Sheets("Columns") _
.Range("rgnMainInfoColumnsToFind").Value
Set colMainInfoColumns = ColumnBuilder(wksMainInfo, avarMainInfoColumnsToFind)
If colMainInfoColumns Is Nothing Then Exit Sub
我使用此函数(如果需要,可以将它放在类模块中)来创建列集合 - 这将查看第1行,修改为第2行或为行号创建新参数。
Private Function ColumnBuilder(wksToSearch As Worksheet, avarColumnsToFind() As Variant) As Collection
'---loops a worksheet and creates collection of columns---
'---collection key = column name without spaces---
Dim colColumns As Collection, clsColumn As cColumn, iIndex As Integer
Dim iColfound As Integer, sError As String
Set colColumns = New Collection
For iIndex = LBound(avarColumnsToFind, 1) To UBound(avarColumnsToFind, 1)
On Error Resume Next
iColfound = wksToSearch.Rows(1).Find(what:=avarColumnsToFind(iIndex, 1), lookat:=xlWhole).Column
On Error GoTo 0
If iColfound > 0 Then
Set clsColumn = New cColumn
clsColumn.Header = avarColumnsToFind(iIndex, 1)
clsColumn.Number = iColfound
colColumns.add clsColumn, ConvertStringToKey(avarColumnsToFind(iIndex, 1))
Else
sError = sError & vbNewLine & avarColumnsToFind(iIndex, 1)
End If
Next
If sError = "" Then
Set ColumnBuilder = colColumns
Else
Set ColumnBuilder = Nothing
MsgBox "Unable to process script as the following columns were not found on " & wksToSearch.Name & ":" _
& vbNewLine & vbNewLine & sError
End If
End Function
Private Function ConvertStringToKey(ByVal sKey As Variant)
sKey = Replace(sKey, " ", "")
ConvertStringToKey = sKey
End Function
然后,您可以按键访问列而不留空格,例如:
返回“租户参考”列的编号:
colMainInfoColumns.Item("TenantReference").Number
计算“Tenant Referance”列中填充的单元格数:
WorksheetFunction.CountA(activesheet.Columns(colMainInfoColumns.Item("TenantReference").Number))