【问题标题】:UserForm command button code - Error 91: Object variable or With block variable not set用户窗体命令按钮代码 - 错误 91:对象变量或未设置块变量
【发布时间】:2016-12-01 00:00:07
【问题描述】:

我有一个命令按钮单击事件的代码,该事件不断引发错误 91。当我单步执行代码时,它会在“设置 findvalue”代码执行后立即引发错误。请参阅下面的代码 sn-p。在检查代码本身时我无法弄清楚。

'findvalue' 被标注为范围对象。 “DataSH”是主数据表所在的工作表,以记录 ID 列(B 列)开头。用户表单元素在 DataSH 上的数据表中设置为它们各自的列。

    Private Sub cmdEdit_Click()
    'declare the variables
    Dim findvalue As Range
    Dim cNum As Integer
    Dim DataSH As Worksheet
    'error handling
    On Error GoTo errHandler:
    'hold in memory and stop screen flicker
    Application.ScreenUpdating = False
    Set DataSH = Sheet1

这个sn-p的点击事件子例程被设置为根据那些UF元素中的值更新DataSH中所选记录ID(行号标识符)的行上的适当列数据(即更改或删除的值)。重点是使用 UF 元素(文本框和组合框)中所做的任何更改来更新 DataSH 上的主数据表。

    Set findvalue = DataSH.Range("B:B"). _
    Find(What:=Me.tbRecID.Value, LookIn:=xlValues, LookAt:=xlWhole)
    'update the values
    findvalue = tbRecID.Value
    findvalue.Offset(0, 1) = tbRecDate.Value
    findvalue.Offset(0, 2) = cmbRecLoc.Value
    findvalue.Offset(0, 3) = cmbRecCust.Value
    findvalue.Offset(0, 4) = tbRecAmt.Value
    findvalue.Offset(0, 5) = cmbRecComm.Value
    findvalue.Offset(0, 6) = cmbRecPrin.Value
    findvalue.Offset(0, 7) = tbRecTerr.Value
    findvalue.Offset(0, 8) = tbRecRep.Value

【问题讨论】:

  • 您使用 Set 语句设置了 findvalue,然后尝试为其分配另一个值。
  • @Rdster,但这不应该引发任何错误,因为它只是确认当前的“findvalue”值
  • @Rdster 一旦在同一个 UF 上的列表框中(从 DataSH 上的数据表中拉出)中的记录被双击(一个单独的子例程),文本框和组合框元素就会被填充。 'findvalue' 设置为在该事件时填充到 tbRecID 文本框元素中的记录 ID。其余代码应该使用“findvalue”对象作为参考点,将 UF 元素(即已更改的元素)中的值返回到 DataSH 表(以及列表框的扩展)中的相应字段。至少我认为我解释得对。
  • 那为什么还要费心寻找呢?如果您只是要分配文本框的值... Find 什么也不做。但是发布的答案之一很可能是您需要的。

标签: vba excel userform


【解决方案1】:

我认为 DataSH 没有设置。 “Sheet1”是工作表的名称还是工作表变量?如果它是一个名称,那么您必须像这样设置 DataSH:

Set DataSH = thisworkbook.worksheets("Sheet1") 

而不是Set DataSH = Sheet1

【讨论】:

  • 这会从“Set DataSH = Sheet1”语句中引发错误
  • 不,按照他的方式工作。只要数据表是 Sheet1。一个是属性窗口中工作表的名称...另一个是(名称)。
  • @user3598756 这就是票!我将其设置为 Excel 默认 Sheet1 名称。我一直在这样做,以前没有任何问题,以防工作表名称被更改。但是,当我将它设置为您的解决方案中的实际工作表名称时,它就像一个魅力。问题解决了。非常感谢1!
  • @Rdster 我也在想同样的事情,但是在改变它之后,子程序现在按预期运行。在这个问题上摸不着头脑。
【解决方案2】:

弹出错误 91(在这种情况下),因为您试图将值分配给尚未设置的某个范围,因此您的 Me.tbRecID.Value 不存在于 DataSH.Range("B:B") 中。为了避免这个问题,你可以添加一些错误异常,例如:

    Set findvalue = DataSH.Range("B:B"). _
    Find(What:=Me.tbRecID.Value, LookIn:=xlValues, LookAt:=xlWhole)
    'update the values
On Error GoTo ErrHand:
    findvalue = tbRecID.Value
On Error GoTo 0
    findvalue.Offset(0, 1) = tbRecDate.Value
    findvalue.Offset(0, 2) = cmbRecLoc.Value
    findvalue.Offset(0, 3) = cmbRecCust.Value
    findvalue.Offset(0, 4) = tbRecAmt.Value
    findvalue.Offset(0, 5) = cmbRecComm.Value
    findvalue.Offset(0, 6) = cmbRecPrin.Value
    findvalue.Offset(0, 7) = tbRecTerr.Value
    findvalue.Offset(0, 8) = tbRecRep.Value
ErrHand:
[rest of your code]

如果没有分配给这个变量的范围,这将强制程序绕过使用findvalue 的行。

【讨论】:

    【解决方案3】:

    您的代码根本无法在“DataSH.Range("B:B")”中找到“Me.tbRecID.Value”

    因此,如果 findvalue 已实际设置为有效范围,则将代码包装在“If Then End If”中以执行

    Set findvalue = DataSH.Range("B:B"). _
    Find(What:=Me.tbRecID.Value, LookIn:=xlValues, LookAt:=xlWhole)
    If Not findvalue Is Nothing Then
        findvalue.Offset(0, 1) = tbRecDate.Value
        findvalue.Offset(0, 2) = cmbRecLoc.Value
        findvalue.Offset(0, 3) = cmbRecCust.Value
        findvalue.Offset(0, 4) = tbRecAmt.Value
        findvalue.Offset(0, 5) = cmbRecComm.Value
        findvalue.Offset(0, 6) = cmbRecPrin.Value
        findvalue.Offset(0, 7) = tbRecTerr.Value
        findvalue.Offset(0, 8) = tbRecRep.Value
    End If
    

    【讨论】:

    • 如果我的回答解决了您的问题,那么您可能希望将其标记为接受。谢谢!
    猜你喜欢
    • 2019-11-16
    • 2014-01-08
    • 2017-04-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-07
    • 2017-05-20
    相关资源
    最近更新 更多