【问题标题】:VBA to set cell contents as Named range nameVBA将单元格内容设置为命名范围名称
【发布时间】:2017-12-13 19:01:20
【问题描述】:

如果单元格以单词“kit”开头,我正在尝试将范围中第一个单元格的前 7 个字符设置为命名范围名称。

这是我目前所拥有的:

Sub DefineRanges()
Dim rngStart As Range
Set rngStart = Range("A1")
Dim LastRow As Integer
Dim RangeName As String

For Each cell In Range("A2:A7")
    If LCase(Left(cell.Value, 3)) = "kit" Then

        RangeName = LCase(Left(cell.Value, 7))

        ActiveWorkbook.Names.Add _
            Name:=RangeName, _
            RefersToLocal:=Range(rngStart.Address & ":C" & cell.Row - 1)
        Set rngStart = Range("A" & cell.Row)

    End If
    LastRow = cell.Row
Next
RangeName = LCase(Left(cell.Value, 7))

ActiveWorkbook.Names.Add _
    Name:=RangeName, _
    RefersToLocal:=Range(rngStart.Address & ":C" & LastRow)
End Sub

基本上我希望它查看我的整个范围,找到以单词“kit”开头的任何单元格,创建一个从该单元格到下一个以“kit”开头的单元格的命名范围,并分配第一个该单元格的 7 个字符作为范围名称。到目前为止,我能够让它创建范围,但是当我尝试将单元格的内容传递到范围名称时遇到问题。有什么想法吗?

【问题讨论】:

  • 你得到什么错误信息,在哪一行?
  • 您试图在循环外引用 cell 这就是错误的原因。
  • ^^^ 单元格在 For Each 循环后变为空
  • 为什么要重复循环外的行,同时也在循环内?
  • 如果任何单元格包含错误,或者任何单元格的内容少于 7​​ 个字符,您就会遇到问题。如果ActiveSheet 不是预期/预期的工作表,并且名称已经定义,则预计会出现其他问题。如果没有指定Option Explicit,您将很快遇到其他更难诊断的问题。始终使用Option Explicit

标签: vba excel


【解决方案1】:

这假设您的数据与上一个问题相似。

它使用 Match 来查找每个 "Kit...",从而节省了一些迭代:

Sub DefineRanges()
Dim rngStart As Long
Dim RangeName As String
Dim col As Long
Dim PreFx As String

col = 1 'change to the column number you need
PreFx = "kat" 'change to the prefix you are looking for

With Worksheets("Sheet7") 'change to your sheet
    On Error Resume Next
        rngStart = Application.WorksheetFunction.Match(PreFx & "*", .Columns(col), 0)
    On Error GoTo 0
    If rngStart > 0 Then
        Do
            i = 0
            On Error Resume Next
                i = Application.WorksheetFunction.Match(PreFx & "*", .Range(.Cells(rngStart + 1, col), .Cells(.Rows.Count, col)), 0) + rngStart
            On Error GoTo 0
            If i > 0 Then
                RangeName = LCase(Left(.Cells(rngStart, col).Value, 7))
                ActiveWorkbook.names.Add name:=RangeName, RefersToLocal:=.Range(.Cells(rngStart, col), .Cells(i - 1, col + 2))
                rngStart = i
            Else 'no more "kit..." so find the last row with data and use that
                i = Application.WorksheetFunction.Match("zzz", .Columns(col))
                RangeName = LCase(Left(.Cells(rngStart, 1).Value, 7))
                ActiveWorkbook.names.Add name:=RangeName, RefersToLocal:=.Range(.Cells(rngStart, col), .Cells(i - 1, col + 2))

            End If
        Loop While i < Application.WorksheetFunction.Match("zzz", .Columns(col))
    End If
End With
End Sub

【讨论】:

  • If rngStart Then 读起来像个黑客。隐式的Long-to-Boolean 转换对于这里的新手来说可能并不明显。
  • @Mat'sMug 你是说我应该rngstart&gt;0 还是解释一下?
  • 我会选择If rngStart &gt; 0 Then,是的。否则很好的答案 - 缺少的只是 IsError 和对单元格值的长度检查,以避免在遇到 #N/AKitKat 在那里时爆炸。
  • 但是匹配不会发现错误,我只在匹配返回的单元格上执行左侧操作。我不明白KitKat 会有什么问题,这是一个真正的问题,因为我没有看到它。 @Mat'sMug
  • @Mat'sMug 这就是为什么我专门使用kittes 只是为了确保。在记住之前,我几乎完成了整个IIF(LEN()&lt;7,LEN(),7)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多