如何将值返回到命名范围而不是使用范围的Offset()

时间:2019-01-31 12:16:30

标签: excel vba named-ranges

警告专家:我是vba的“初学者” ...

我有一本工作簿,用于根据产品名称查找产品的属性。例如。命名范围“ Album_Name”中具有“ John Coltrane的我的最爱”的单元格应返回命名范围“ Musician”中的“ John Coltrane”值,命名范围“ Music_genre”中的“ Jazz”值(偏移命名范围“ 78列的相册名称)等

我目前正在使用此

Sub UpdateAttributes()

    Dim c As Range
    Dim i As Integer
    Dim vezesQueEncontrouNumero As Integer
    Dim posicaoSegundoNumero As Integer

    For Each c In Range("Album_Name", Range("Album_Name ").End(xlDown))

    vezesQueEncontrouNumero = 0
    posicaoSegundoNumero = -1

    For i = 1 To Len(c)

        If IsNumeric(Mid(c, i + 1, 1)) Then
            vezesQueEncontrouNumero = vezesQueEncontrouNumero + 1
            If (vezesQueEncontrouNumero) = 2 Then
                posicaoSegundoNumero = i
            End If
        End If
    Next
**If InStr(UCase(c.Value), UCase("John Coltrane")) > 0 Then c.Offset(0, 78).Value = "Jazz"**

我的问题: 随着属性数量的增加,通过正确的列数进行“ c.Offset”变得更加困难。而且有时我必须在它们之间添加列,这确实变得不可行!有没有一种方法可以将 c.Value放在命名范围内,而不使用Offset

谢谢。


更新

在@Luuklag,@wallyeye,@JvdV和-特别-@nwhaught的帮助下,我重写了vba,但仍然无济于事。我仍然想念一些东西。 vba在同一列(“名称”)中而不是在“流派”或“艺术家”列中更改单元格的值。 (我确实在A1中输入了“名称”,在B1中输入了“流派”,在C1中输入了“艺术家”)。某种程度上,“ colNum”的“属性”不起作用。

    Sub UpdateProductAttributes()

    Dim colNum As Integer
    For colNum = 1 To 100 'or however many populated columns you end up having...
        Select Case Sheet1.Cells(1, colNum) 'Look at the column header
            Case "Genre" 'If you've found the "Genre" column
                genreColumn=colNum 'Give the genreColumn variable the correct value
            Case "Artist"
                artistColumn=colNum
        End Select
    Next

   Dim c As Range
    Dim i As Integer
    Dim vezesQueEncontrouNumero As Integer
    Dim posicaoSegundoNumero As Integer

    For Each c In Range("name", Range("name").End(xlDown))
    vezesQueEncontrouNumero = 0
    posicaoSegundoNumero = -1
        For i = 1 To Len(c)

            If IsNumeric(Mid(c, i + 1, 1)) Then
            vezesQueEncontrouNumero = vezesQueEncontrouNumero + 1

            If (vezesQueEncontrouNumero) = 2 Then
            posicaoSegundoNumero = i

            End If
            End If

    Next i

        If InStr(UCase(c.Value), UCase("Coltrane")) > 0 Then
            c.Offset(0, genreColumn).Value = "Jazz"

            ElseIf InStr(UCase(c.Value), UCase("Brad Spreadsheet")) > 0 Then
            c.Offset(0, genreColumn).Value = "Indie Folk Grunge"

        End If
        Next c
End Sub

怎么了?

1 个答案:

答案 0 :(得分:0)

展开一些评论: 索引匹配是一种模式,通常在单元格公式中用作VLOOKUP的更灵活的伴侣。

它的工作原理如下:=INDEX(YourTotalRangeOfData,MATCH("YourSearchKey",TheColumnRangeOfYourSearchKey,0),TheNumberOfTheColumnInYourTotalRangeThatYouWantToReturn)

实际上,它看起来像这样:=INDEX(C3:E11,MATCH("Frantz",B3:B11,0),2)

在单元格中,Excel将为您跟踪更改。在代码中,您将继续遇到更改列引用号的问题。

wallyeye关于设置列变量的评论很好,您可以这样做:

Dim genreColumn as Integer
genreColumn = 78

**If InStr(UCase(c.Value), UCase("John Coltrane")) > 0 Then c.Offset(0, genreColumn).Value = "Jazz"**

在我看来,更好的方法是在代码的开头运行一个“设置”部分。设置部分的目的是为您设置所有列变量。像这样:

Dim colNum as Integer
For colNum = 1 to 100 'or however many populated columns you end up having...
    Select Case Sheet1.Cells(1, colNum) 'Look at the column header
        Case "Genre" 'If you've found the "Genre" column
            genreColumn = colNum 'Give the genreColumn variable the correct value
        Case "Artist"
            artistColumn = colNum
    End Select
Next

在代码的开头运行该命令,您不必担心再次更改列的位置。只要您具有正确的列标题(更容易检查),您就可以拥有正确的编号。

另外,要回应别人的言论,您做得很好。这看起来不像“初级”初学者的代码。 :)