【问题标题】:UDF function to name a range用于命名范围的 UDF 函数
【发布时间】:2014-05-26 09:01:12
【问题描述】:

我需要一个小 UDF 来命名 Excel 中的范围,但它不断返回 #VALUE 错误。与 sub 做同样的事情就像一个魅力,但不是我想要的,因为我想命名大量的范围。 首先是子:

Sub setNamedRanges()
    ' input values
    inputRange = "A4"
    newName = "Tank101"

    ' removing spaces from the name
    newName = Replace(newName, " ", "")

    ' write the name
    Range(inputRange).name = newName
End Sub

现在与函数相同(inputRange = "A4" 和 newName = "Tank101"),它应该在完成后返回“成功”但根本不起作用:

Function setNamedRange(inputRange, newName)

    ' removing spaces from the name
    newName = Replace(newName, " ", "")

    ' write the name
    Range(inputRange).name = newName

    setNamedRange = "succesful"
End Function

我做错了什么?将具有所需值的数组读入 sub 肯定会起作用,但不能提供完整的功能。

【问题讨论】:

    标签: vba excel


    【解决方案1】:

    函数不能更改工作簿。范围是工作簿/工作表属性,因此不能由函数更改。函数可以将结果返回到工作表,但这不是属性,所以没关系。另一方面, subs 不能返回任何东西,但他们可以修改属性。

    【讨论】:

    • 感谢您的回答,我找到了问题的答案。这是可能的,但相当困难且不可取,请参阅link
    • 查看建议的解决方案,它对我来说效果很好,并且可以扩展到所有其他工作簿更改事件。
    【解决方案2】:

    你可以试试下面的代码。效果很好:

    Sub setNamedRanges()
        Dim newName As String
        newName = "Tank101"
        Dim inputRange As Range
        Set inputRange = Range("A4")
        inputRange.name = newName
    End Sub
    

    如果您有任何疑问,请告诉我。

    问候

    【讨论】:

    • 不幸的是,这根本无法解决我的问题。您的解决方案正在使用 sub 并且已经可以正常工作(尽管您的代码更好)。如何使用函数做同样的事情?
    【解决方案3】:

    好的,你可以试试下面的其他方法:

    Sub Button1_Click()
       Call ChangeValue("Tank101", "Alibaba")
    End Sub
    
    Sub ChangeValue(cellAddress, newValue)
        Dim inputRange As Range
        Set inputRange = Range(cellAddress)
        inputRange.Name = newValue
    End Sub
    

    如果您有任何疑问,请告诉我。

    【讨论】:

    • 感谢您的回复,但此解决方案仍然根本不是动态的。我想重命名数百个单元格,这就是我想使用函数的原因。
    • 请说明你的期望,我会帮你解决的!
    • 感谢您的努力,但我已经找到了解决方案。见我上面的回答。
    【解决方案4】:

    在 Marks 答案的帮助下,我为我的问题找到了以下解决方案,请参阅下面的解决方案。它有点长而且不是直截了当的,但它确实有效。调用

    giveNameToRange("Tank101")
    

    在单元格内,给这个单元格命名为“Tank 101”。代码是:

    Private Declare Function SetTimer Lib "user32" ( _
          ByVal HWnd As Long, _
          ByVal nIDEvent As Long, _
          ByVal uElapse As Long, _
          ByVal lpTimerFunc As Long _
       ) As Long
    
    Private Declare Function KillTimer Lib "user32" ( _
          ByVal HWnd As Long, _
          ByVal nIDEvent As Long _
       ) As Long
    
    Private mCalculatedCells As Collection
    Private mWindowsTimerID As Long
    Private mApplicationTimerTime As Date
    
    Public Function giveNameToRange(newName) As String
    
    ' This is a UDF that returns the sum of two numbers and starts a windows timer
    ' that starts a second Appliction.OnTime timer that performs activities not
    ' allowed in a UDF. Do not make this UDF volatile, pass any volatile functions
    ' to it, or pass any cells containing volatile formulas/functions or
    ' uncontrolled looping will start.
    
       newName = Replace(newName, " ", "")
       giveNameToRange = newName
    
       ' Cache the caller's reference so it can be dealt with in a non-UDF routine
       If mCalculatedCells Is Nothing Then Set mCalculatedCells = New Collection
       On Error Resume Next
       mCalculatedCells.Add Application.Caller, Application.Caller.Address
       On Error GoTo 0
    
       ' Setting/resetting the timer should be the last action taken in the UDF
       If mWindowsTimerID <> 0 Then KillTimer 0&, mWindowsTimerID
       mWindowsTimerID = SetTimer(0&, 0&, 1, AddressOf AfterUDFRoutine1)
    
    End Function
    
    Public Sub AfterUDFRoutine1()
    
    ' This is the first of two timer routines. This one is called by the Windows
    ' timer. Since a Windows timer cannot run code if a cell is being edited or a
    ' dialog is open this routine schedules a second safe timer using
    ' Application.OnTime which is ignored in a UDF.
    
       ' Stop the Windows timer
       On Error Resume Next
       KillTimer 0&, mWindowsTimerID
       On Error GoTo 0
       mWindowsTimerID = 0
    
       ' Cancel any previous OnTime timers
       If mApplicationTimerTime <> 0 Then
          On Error Resume Next
          Application.OnTime mApplicationTimerTime, "AfterUDFRoutine2", , False
          On Error GoTo 0
       End If
    
       ' Schedule timer
       mApplicationTimerTime = Now
       Application.OnTime mApplicationTimerTime, "AfterUDFRoutine2"
    
    End Sub
    
    Public Sub AfterUDFRoutine2()
    
    ' This is the second of two timer routines. Because this timer routine is
    ' triggered by Application.OnTime it is safe, i.e., Excel will not allow the
    ' timer to fire unless the environment is safe (no open model dialogs or cell
    ' being edited).
    
       Dim Cell As Range
    
       ' Do tasks not allowed in a UDF...
       Application.ScreenUpdating = False
       Application.Calculation = xlCalculationManual
       Do While mCalculatedCells.Count > 0
          Set Cell = mCalculatedCells(1)
          mCalculatedCells.Remove 1
          Cell.name = Cell.Value
       Loop
       Application.Calculation = xlCalculationAutomatic
       Application.ScreenUpdating = True
       End Sub
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多