Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/vba/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Excel 如何应用InStr将标题名与名称数组匹配?_Excel_Vba - Fatal编程技术网

Excel 如何应用InStr将标题名与名称数组匹配?

Excel 如何应用InStr将标题名与名称数组匹配?,excel,vba,Excel,Vba,我的宏应该将标题名与名称数组相匹配 如果为true,则省略它 如果不是,则将第二行到最后一行的值设置为Customer 最初,我在“Else”部分有客户值,但宏按设想做了相反的事情——只更改了数组值上的单元格。这对我来说没有意义,因为我认为我已经将InStr函数设置为正输出,但是我将指令放在匹配部分 在70个变量中,有67个按预期积极,3个变量被命名为客户,其中很少有变量不是从第二个变量到最后一个变量,但例如,只有第二个变量,或者只有少数变量 子测试2() 昏暗的头部,如射程 朦胧的头像 H

我的宏应该将标题名与名称数组相匹配

  • 如果为true,则省略它
  • 如果不是,则将第二行到最后一行的值设置为Customer
最初,我在“Else”部分有客户值,但宏按设想做了相反的事情——只更改了数组值上的单元格。这对我来说没有意义,因为我认为我已经将InStr函数设置为正输出,但是我将指令放在匹配部分

在70个变量中,有67个按预期积极,3个变量被命名为客户,其中很少有变量不是从第二个变量到最后一个变量,但例如,只有第二个变量,或者只有少数变量

子测试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的最后一个单元格