Excel 如何应用InStr将标题名与名称数组匹配?
我的宏应该将标题名与名称数组相匹配Excel 如何应用InStr将标题名与名称数组匹配?,excel,vba,Excel,Vba,我的宏应该将标题名与名称数组相匹配 如果为true,则省略它 如果不是,则将第二行到最后一行的值设置为Customer 最初,我在“Else”部分有客户值,但宏按设想做了相反的事情——只更改了数组值上的单元格。这对我来说没有意义,因为我认为我已经将InStr函数设置为正输出,但是我将指令放在匹配部分 在70个变量中,有67个按预期积极,3个变量被命名为客户,其中很少有变量不是从第二个变量到最后一个变量,但例如,只有第二个变量,或者只有少数变量 子测试2() 昏暗的头部,如射程 朦胧的头像 H
- 如果为true,则省略它
- 如果不是,则将第二行到最后一行的值设置为Customer
子测试2()
昏暗的头部,如射程
朦胧的头像
HeaderName=Join(数组(“ID”、“性别”、“收入”))
设置HeaderRow=范围(单元格(1,1),单元格(1,1)。结束(xlToRight))
对于HeaderRow中的每个收割台
打印头
调试。打印标题名
如果InStr(1,HeaderName,Header.Value,vbTextCompare)=0,则
范围(单元格(2,标题.列).地址,单元格(单元格(行.计数,标题.列).结束(xlUp).行,标题.列).地址).值2=“客户”
其他的
如果结束
下一包头
端接头
例如,列BD是它应该是的,所有这些列都有间隙,但BD、BF、BG、BO是好的(该特定文件上的1-59行,其余的不是)
加上前面提到的内容-有时标题设置为customer和first row,而不是其他内容。New HeaderRow使我不匹配,当我更改为ws.Range时,它最初只得到第一列,就像不是drag xlToLeft
只需循环检查此工作簿中每个ws的所有工作表
。工作表并确保所有范围、单元格、行和列对象都与工作表一起引用,如ws.Range
等
Option Explicit
Public Sub test2()
Dim ws As Worksheet
For Each ws In ThisWorkbook.Worksheets 'loop all worksheets
Dim HeaderName As String
HeaderName = Join(Array("ID", "GENDER", "REVENUE"))
Dim HeaderRow As Range
Set HeaderRow = ws.Range(ws.Cells(1, 1), ws.Cells(1, 1).End(xlToRight))
Dim Header As Variant
For Each Header In HeaderRow
Debug.Print Header
Debug.Print HeaderName
If InStr(1, HeaderName, Header.Value, vbTextCompare) = 0 Then
ws.Range(ws.Cells(2, Header.Column), ws.Cells(ws.Rows.Count, Header.Column).End(xlUp)).Value2 = "Customer"
End If
Next Header
Next ws
End Sub
请注意,范围
对象可以将单元格
作为参数,并且不需要地址
,因此您可以缩短它
Range(Cells(2, Header.Column).Address, Cells(Cells(Rows.Count, Header.Column).End(xlUp).Row, Header.Column).Address).Value2 = "Customer"
到
根据评论思考
如果标题更改,则表示ws.Cells(ws.Rows.Count,header.Column).End(xlUp)
在标题处结束,因为下面没有数据。所以这个范围
ws.Range(ws.Cells(2, Header.Column), ws.Cells(ws.Rows.Count, Header.Column).End(xlUp)).Value2 = "Customer"
实际上是从第2行到第1行。要防止出现这种情况,您需要将其拆分并测试:
Dim LastCellInCol As Range
Set LastCellInCol = ws.Cells(ws.Rows.Count, Header.Column).End(xlUp)
If LastCellInCol.Row >= 2 Then 'only change if there is data in the column
ws.Range(ws.Cells(2, Header.Column), LastCellInCol).Value2 = "Customer"
End If
如果空格应一直填充到所有列的最后一行
Option Explicit
Public Sub test2()
Dim ws As Worksheet
For Each ws In ThisWorkbook.Worksheets 'loop all worksheets
Dim HeaderName As String
HeaderName = Join(Array("ID", "GENDER", "REVENUE"))
Dim LastUsedCell As Range 'find last used cell of ALL columns
Set LastUsedCell = Nothing 'initialize (because inside loop)
Set LastUsedCell = ws.UsedRange.Find("*", , , , xlByRows, xlPrevious)
If Not LastUsedCell Is Nothing Then 'prevent error on empty sheets
Dim HeaderRow As Range
Set HeaderRow = ws.Range(ws.Cells(1, 1), ws.Cells(1, ws.Cells.Columns.Count).End(xlToLeft))
Dim Header As Variant
For Each Header In HeaderRow
If InStr(1, HeaderName, Header.Value, vbTextCompare) = 0 Then
ws.Range(ws.Cells(2, Header.Column), ws.Cells(LastUsedCell.Row, Header.Column)).Value2 = "Customer"
End If
Next Header
End If
Next ws
End Sub
只需为此工作簿中的每个ws循环所有工作表。工作表,并确保所有范围、单元格、行和列对象都被工作表引用,如ws.Range
等
Option Explicit
Public Sub test2()
Dim ws As Worksheet
For Each ws In ThisWorkbook.Worksheets 'loop all worksheets
Dim HeaderName As String
HeaderName = Join(Array("ID", "GENDER", "REVENUE"))
Dim HeaderRow As Range
Set HeaderRow = ws.Range(ws.Cells(1, 1), ws.Cells(1, 1).End(xlToRight))
Dim Header As Variant
For Each Header In HeaderRow
Debug.Print Header
Debug.Print HeaderName
If InStr(1, HeaderName, Header.Value, vbTextCompare) = 0 Then
ws.Range(ws.Cells(2, Header.Column), ws.Cells(ws.Rows.Count, Header.Column).End(xlUp)).Value2 = "Customer"
End If
Next Header
Next ws
End Sub
请注意,范围
对象可以将单元格
作为参数,并且不需要地址
,因此您可以缩短它
Range(Cells(2, Header.Column).Address, Cells(Cells(Rows.Count, Header.Column).End(xlUp).Row, Header.Column).Address).Value2 = "Customer"
到
根据评论思考
如果标题更改,则表示ws.Cells(ws.Rows.Count,header.Column).End(xlUp)
在标题处结束,因为下面没有数据。所以这个范围
ws.Range(ws.Cells(2, Header.Column), ws.Cells(ws.Rows.Count, Header.Column).End(xlUp)).Value2 = "Customer"
实际上是从第2行到第1行。要防止出现这种情况,您需要将其拆分并测试:
Dim LastCellInCol As Range
Set LastCellInCol = ws.Cells(ws.Rows.Count, Header.Column).End(xlUp)
If LastCellInCol.Row >= 2 Then 'only change if there is data in the column
ws.Range(ws.Cells(2, Header.Column), LastCellInCol).Value2 = "Customer"
End If
如果空格应一直填充到所有列的最后一行
Option Explicit
Public Sub test2()
Dim ws As Worksheet
For Each ws In ThisWorkbook.Worksheets 'loop all worksheets
Dim HeaderName As String
HeaderName = Join(Array("ID", "GENDER", "REVENUE"))
Dim LastUsedCell As Range 'find last used cell of ALL columns
Set LastUsedCell = Nothing 'initialize (because inside loop)
Set LastUsedCell = ws.UsedRange.Find("*", , , , xlByRows, xlPrevious)
If Not LastUsedCell Is Nothing Then 'prevent error on empty sheets
Dim HeaderRow As Range
Set HeaderRow = ws.Range(ws.Cells(1, 1), ws.Cells(1, ws.Cells.Columns.Count).End(xlToLeft))
Dim Header As Variant
For Each Header In HeaderRow
If InStr(1, HeaderName, Header.Value, vbTextCompare) = 0 Then
ws.Range(ws.Cells(2, Header.Column), ws.Cells(LastUsedCell.Row, Header.Column)).Value2 = "Customer"
End If
Next Header
End If
Next ws
End Sub
此InStr(1,HeaderName,Header.Value,vbTextCompare)=0
表示不匹配Instr
返回找到字符串的位置,如果返回0
,则表示未找到字符串。因此,您的代码读起来像“如果未找到字符串,则
替换数据否则
不做任何事如果
结束”对我来说,代码工作完美,没有问题。谢谢。我已经修改了一点,它得到了一致性!但是,如果我的标准解决方案不起作用,你知道如何在所有工作表上循环吗?我已经将ws设置为工作表,然后在上面为我在此工作簿中的每个ws设置了每个标题。工作表,然后在下一个标题之后的最后,我设置了下一个ws,但它并没有遍历所有ws,只是一个活动。您需要使用工作表引用您的范围和单元格ws
。请参阅下面我的答案。此InStr(1,HeaderName,Header.Value,vbTextCompare)=0
表示不匹配Instr
返回找到字符串的位置,如果返回0
,则表示未找到字符串。因此,您的代码读起来像“如果未找到字符串,则
替换数据否则
不做任何事如果
结束”对我来说,代码工作完美,没有问题。谢谢。我已经修改了一点,它得到了一致性!但是,如果我的标准解决方案不起作用,你知道如何在所有工作表上循环吗?我已经将ws设置为工作表,然后在上面为我在此工作簿中的每个ws设置了每个标题。工作表,然后在下一个标题之后的最后,我设置了下一个ws,但它并没有遍历所有ws,只是一个活动。您需要使用工作表引用您的范围和单元格ws
。请看下面我的答案。谢谢!对于缺乏一致性有什么建议吗?由于宏的原因,似乎很少有变量更改了标题,或者它们并没有将所有单元格都填充为Customer(它们是空的)reason@rainbowthug有关更改的标题,请参见我编辑的答案。我无法重现矛盾。请注意,Set HeaderRow=ws.Range(ws.Cells(1,1),ws.Cells(1,1).End(xlToRight))
如果头中有空格,您必须使用Set HeaderRow=ws.Cells(ws.Cells(1,1),ws.Cells(1,ws.Columns.Count).End(xlToLeft))
。你能给出一个小例子来产生上面提到的空白吗?我已经更新了最初的问题,谢谢你的帮助看到我编辑的答案。您需要找到所有列的最后一个单元格,而不是每个indi的最后一个单元格