macros根据标题值连接两列

我有一个Excel电子表格中包含许多列的两列。 我想合并这两列,但他们在表中的位置可能会有所不同。 这意味着我需要利用第一行的列标题来确定要连接的两列。 我希望将结果添加为表单中的下一列。

例如,“品牌”,“行”和“产品”在第1行作为列标题,macros应search“品牌”中的值,并将其与“模型”中的值连接,并将结果放入(在本例中为D,但可能会根据列数而改变),因为品牌和型号列的位置可能会发生变化,所以我不能使用列或单元格引用。列:

A | B | C |
品牌| 行| 模型|
宾得| 相机| K-30 |
本田| 自动| Accord |
苹果| 计算机| MacBook Air |

以下是我所尝试的:

Sub Insrt() Dim Model As Range Dim Brand As Range Dim LastRow As Long Set Brand = Rows(1).Find(what:="Brand", LookIn:=xlValues, lookat:=xlWhole) Set Model = Rows(1).Find(what:="Model", LookIn:=xlValues, lookat:=xlWhole) If Found Is Nothing Then Exit Sub LastRow = Cells(Rows.Count, Brand.Column).End(xlUp).Row Model.Offset(, 1).EntireColumn.Insert Cells(1, Model.Column + 1).Value = "Concatenated_Value" Range(Cells(2, Model.Column + 1), Cells(LastRow, Model.Column + 1)).Formula = "=A2&C2" End Sub 

这种方法的问题是,我的公式是专门连接A和C列。然而,品牌和模型可能并不是每次都在这些特定的列中 – 将来它们可能会改变位置。 我怎样才能改善这一点,以便我不明确地调出列A和C,而是使用列标题?

我喜欢使用索引/匹配:

 =F2 & " " &INDEX(A:C,MATCH(F2,A:A,0),MATCH("Model",1:1,0)) 

在这里输入图像说明

无论“模型”在哪里结束,它都会find正确的列。

对于VBA。 将公式更改为

 "=" & Cells(2,brand.column).address(0,0) & "&" & Cells(2,model.column).address(0,0) 

尝试:

 =HLOOKUP("Brand",A:C,ROW(),0) & " " & HLOOKUP("Model",A:C,ROW(),0) 

我修改了编辑的原始问题中的代码。

1-选项显式总是一个好主意。

2-确定了2列的标题search,更多的DRY,特别是如果需要添加更多的列被发现。

2.A也是“如果发现没有那么”testing不起作用,至less不在我的箱子。 即使它起作用,也没有任何信息。 无声的失败可能是好的,但往往是不好的。 现在任何未find的标题都会显示一条消息。

2.b-增加了MatchCase:= True查找()也许这个改变不是我们想要的,但是可以certificateDRY代码(Do not Repeat Yourself)的帮助。 如果你不喜欢这种变化,你只能编辑一个地方来改变它,而不是2,3或4个地方编辑每个头被发现。

3-一个答案有片段“Cells(2,brand.column).address(0,0)”,但Range对象上的Address()方法以大写字母A开头,但Excel ADDRESS函数全部大写。 ADDRESS函数文档说ADDRESS(0,0)是一个OK调用,但是Range对象doc上的Address(0,0)方法说这两个0值是由Address()查看的变体为True或不是。

我修改为.Address(RowAbsolute:= False),所以不必将0理解为False,并且我们还希望ColumnAbsolute为True,这是默认值。 我们想要一个绝对的,一个亲戚,所以混淆他们是相同的编码地址(0,0)

4-variablesFormula9只是为了使debugging更容易。 它可以在debugging后编辑出来。 另一方面,它是如何被分配的细胞(2,Brand.Column).Address(RowAbsolute:= False)的重复

所以也许一个函数来分解'Cells(x,y).Address(RowAbsolute:= False)'会更干。

需要多less个临时variables,多less分解才能使代码更加干净才是判断调用。

 Option Explicit Function FindOrMsg(toFind As String) As Range Dim Rtn As Range Set Rtn = Rows(1).Find(what:=toFind, LookIn:=xlValues, _ lookat:=xlWhole, MatchCase:=True) Set FindOrMsg = Rtn If Rtn Is Nothing Then MsgBox "Header '" & toFind & "' not found" End Function Sub Macro1() Dim Model As Range Dim Brand As Range Dim LastRow As Long Set Brand = FindOrMsg("Brand") Set Model = FindOrMsg("Model") If (Brand Is Nothing) Or (Model Is Nothing) Then Exit Sub LastRow = Cells(Rows.Count, Brand.Column).End(xlUp).Row Model.Offset(, 1).EntireColumn.Insert Cells(1, Model.Column + 1).Value = "Concatenated_Value" Dim Formula9 Formula9 = "=" & Cells(2, Brand.Column).Address(RowAbsolute:=False) & "&" _ & Cells(2, Model.Column).Address(RowAbsolute:=False) & "" Range(Cells(2, Model.Column + 1), Cells(LastRow, Model.Column + 1)).Formula = Formula9 End Sub