在函数VBA中传递对象变量时出现问题

时间:2017-03-08 16:26:16

标签: excel vba excel-vba

我有一个程序,它接受用户输入并根据作业类型将其放在工作表中。出于此目的,我们只关注Sheet(" Active Jobs")。

我有一个函数从UserForm获取信息,并根据jobID将其放入Cells中。简单计数会跟踪JobID,并根据其ID将作业放入工作表中,如下所示:

Public btn As Button
Public t As Range

Function GetActiveJob()

Dim i1 As Integer
i1 = Worksheets("Sheet1").Range("C4").Value '//Keeps count of jobs, gives the JobID

  With Worksheets("Active Jobs")
    .Range("A" & (5 * i1)) = UserForm1.TextBox1
    ActiveSheet.Range("B" & (5 * i1) & ":" & "E" & (3 + (5 * i1))).Merge
    .Range("B" & (5 * i1)) = UserForm1.TextBox2  '//Handles a decent bit of text 
    .Range("B" & (5 * i1) & ":" & "E" & (3 + (5 * i1))).VerticalAlignment = xlTop
    Set t = ActiveSheet.Range("G" & (5 * i1))
    Set btn = Worksheets("Active Jobs").Buttons.Add(t.Left, t.Top, t.Width, t.Height)

  With btn
    .Name = "RemovetoArchive" & i1
    .Caption = "Archive"
    .OnAction = "RemovetoArchive"
  End With

  End With

UserForm1.TextBox1.Value = ""
UserForm1.TextBox2.Value = ""

i1 = i1 + 1
Worksheets("Sheet1").Range("C4").Value = i1
MsgBox ("I1 = " & i1) 'For testing purposes

End Function

(作业ID不必是唯一的)

如您所见,userform创建一个按钮,其名称(函数名称)后跟jobID。

当一份工作完成后,&按下存档按钮,我想将其移动到一个名为存档的新工作表中。

要做到这一点,我取字符串并操纵它来获取ID号,然后将字符串转换为整数:

  Function RemovetoArchive()

    Dim ButtonID As Integer
    Dim ButtonString As String

    ButtonString = Mid(btn.Name, 16, 2)  '<-- Error here, (see below)
    ButtonID = CInt(ButtonString)

    Worksheets("Active Jobs").Range("A" & (5 * ButtonID) & ":R" & (3 + (5 * ButtonID))).Select


    MsgBox ("ButtonID is " & ButtonID) 'Testing

ID号用作变量,以确定需要选择的范围,并移至存档。

然而,运行这个,我得到了

Object variable or With Block Variable not set

我在设置btn.Name对象时遇到问题。 即

I enter a job with JobID '5'
The information is created along with a button.
I press Button 5, a.k.a "RemovetoArchive5"

我的代码应该只接受字符串中的数字字符&#34; RemovetoArchive5&#34;并将其转换为整数,以用作ButtonID。

现在,btn.Name,没有值

btn.Name = "RemovetoArchive5"

这是否必须在GetActiveJobs函数中完成?在单击它引用的按钮后,如何传递btn.Name对象?

非常感谢任何帮助。

1 个答案:

答案 0 :(得分:1)

使用您在创建按钮时创建的临时对象的名称,最多可以返回您创建的最后一个名称 - 即使该临时对象是垃圾也不可能-collected。

因此,如果要查找调用Name的按钮的RemoveToArchive,您应该执行以下操作,使用Application.Caller确定按下了哪个按钮:

Sub RemovetoArchive()  'Only use Function when you have a function,
                       'use Sub when you have a subroutine
    Dim ButtonID As Integer
    Dim ButtonString As String

    ButtonString = Mid(Application.Caller, 16, 2)
    ButtonID = CInt(ButtonString)

    Worksheets("Active Jobs").Range("A" & (5 * ButtonID) & ":R" & (3 + (5 * ButtonID))).Select

    MsgBox ("ButtonID is " & ButtonID) 'Testing

End Sub

Mark Fitzgerald随后对该问题的评论也让我发现您的GetActiveJob代码存在潜在问题。您的代码部分说:

With Worksheets("Active Jobs")
  .Range("A" & (5 * i1)) = UserForm1.TextBox1
  ActiveSheet.Range("B" & (5 * i1) & ":" & "E" & (3 + (5 * i1))).Merge
  .Range("B" & (5 * i1)) = UserForm1.TextBox2  '//Handles a decent bit of text 
  .Range("B" & (5 * i1) & ":" & "E" & (3 + (5 * i1))).VerticalAlignment = xlTop
  Set t = ActiveSheet.Range("G" & (5 * i1))
  Set btn = Worksheets("Active Jobs").Buttons.Add(t.Left, t.Top, t.Width, t.Height)

  With btn
    .Name = "RemovetoArchive" & i1
    .Caption = "Archive"
    .OnAction = "RemovetoArchive"
  End With

End With

有一些对ActiveSheet的引用。如果活动表不是&#34;活动作业&#34;然后会导致问题的工作表。 (但如果您始终确保活动工作表 &#34;活动工作&#34;它显然会有效。)为避免出现问题,我建议您将该代码更改为:

With Worksheets("Active Jobs")
  .Range("A" & (5 * i1)) = UserForm1.TextBox1
  .Range("B" & (5 * i1) & ":" & "E" & (3 + (5 * i1))).Merge
  .Range("B" & (5 * i1)) = UserForm1.TextBox2  '//Handles a decent bit of text 
  .Range("B" & (5 * i1) & ":" & "E" & (3 + (5 * i1))).VerticalAlignment = xlTop
  Set t = .Range("G" & (5 * i1))
  Set btn = .Buttons.Add(t.Left, t.Top, t.Width, t.Height)

  With btn
    .Name = "RemovetoArchive" & i1
    .Caption = "Archive"
    .OnAction = "RemovetoArchive"
  End With

End With