2017-03-08 73 views
0

我有一个程序,根据作业类型,将用户输入信息放在工作表中。为了达到这个目的,我们只关注图纸(“活动作业”)。在函数VBA中传递对象变量时出现故障

我有一个函数,它从UserForm获取信息,并根据jobID将它放入单元格中。一个简单的计数跟踪的作业ID,并且工作放入纸张,根据其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不一定是唯一的)

正如你所看到的,用户窗体创建一个名称(函数的名称)后跟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" 

我的代码应该从字符串“RemovetoArchive5”只取数字字符,并将其转换为整数,用作ButtonID。

因为它是现在,btn.Name,不具备价值

btn.Name = "RemovetoArchive5" 

请问这个有在GetActiveJobs功能做?点击它引用的按钮后,如何传递btn.Name对象?

任何帮助将不胜感激。

+0

术语“传递对象变量的函数“通常意味着*参数*,而你的函数没有。你读过*参数*吗? 'btn'似乎是一个模块级变量,又名“公共领域”或“全局变量”,这是“传递参数” –

+0

@SJR这为我提供了相同的结果。我现在有,通过测试的对面,也许更合乎逻辑。我认为我遇到的问题是,在调用“RemovetoArchive”函数时,btn.Name属性未设置,即没有值,因此无法操作字符串。 –

+0

如果错误是运行时错误91,那么它不是'Name'属性没有值,它是'btn'引用本身; 'btn'是'Nothing'。在哪个模块中声明了'btn'?一个标准/程序模块?工作表/类模块?用户表单的代码隐藏?请参阅Documentation.SO的VBA主题中的[Variables and Scopes](http://stackoverflow.com/documentation/vba/877/declaring-variables/2957/variables#t=201703081638244410797)。 –

回答

1

使用您在创建按钮就可以,充其量,返回你所创建的最后一个名称创建一个临时对象的名称 - 甚至认为将是不可能的,一旦该临时对象是garbage-集。

所以,如果你想找到调用RemoveToArchive按钮的Name,你应该做类似下面的,它使用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 

一随后对马克菲茨杰拉德对这个问题的评论也让我看到你的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有一些引用。如果活动工作表不是“活动工作”工作表,则会导致问题。(但它显然会工作,如果你总是确保活动工作表“活动作业”。)为了避免出现问题,我建议你更改代码:

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 
+0

这解决了它,感谢您的额外信息。作业被放置在由三个选项按钮之一的值确定的页面上。所以我打算做这样的事情: 例如,如果optionbutton2.value = true,那么 Sheet2.activate 例如,但你的建议肯定是更好的imo。谢谢! –