excel 用于保存上次单击的工作表的公共变量

db2dz4w8  于 2023-02-20  发布在  其他
关注(0)|答案(1)|浏览(82)

我有一个工作簿,其中有几个工作表,这些工作表包含打开要填写的同一个用户窗体的单元格。
当前,关闭窗体会将工作簿返回到特定的一页。
我正在尝试返回到之前正在处理的页面。
我设置了一个公共工作表变量(wsWorking),该变量将被设置为打开UserForm之前最后一次单击的工作表。
我得到:
运行时间错误"9":下标超出范围
并且调试消息显示我的wsWorking变量为空。
如果我输入工作表的名称而不是尝试使用变量,我就可以打开它到我想要的页面。
声明:'(在我的ThisWorkbook模块中,(常规)(说明)

Public wsWorking As Worksheet

尝试设置:'(在私有模块中,删除了无关代码)

Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)
    Set wsWorking = ThisWorkbook.Worksheets("MRL 1")
    Dim clickRow As Integer
    Dim ClickCol As Integer

尝试使用:(在另一个私有模块中)

Private Sub CloseForm_Click()
    Call SaveFormToScorecard_Click
    Unload Me
    ActiveWorkbook.Sheets(wsWorking).Activate
End Sub

当工作表被激活时,我试着在模块的通用声明中设置wsWorking,并在模块中创建了一个公共sub,只是为了设置该变量,但都不起作用。
变化

ActiveWorkbook.Sheets(wsWorking).Activate

wsWorking.Activate

给我一个新错误
运行时错误"424":需要对象
我不相信一个模块中的变量设置会转移到另一个模块中。

gwbalxhn

gwbalxhn1#

ThisWorkbook是一个类模块,它有一个PredeclaredId属性,可以从任何地方访问它,但是它的成员仍然是 its 成员。你可以从代码的任何地方访问ThisWorkbook的任何公共成员,方法是用预先声明的ThisWorkbook对象限定它:

Debug.Print ThisWorkbook.wsWorking.Name

如果你想要一个 global 变量,那么你就不能使用object模块,因为对象需要一个示例(自动创建的ThisWorkbook示例并没有减少它的对象示例)。相反,在一个 standard module 中声明一个公共变量,然后你可以在代码的任何地方不加限定地访问它,无论是读还是写。
等等,大声说出来。
然后你可以从代码的任何地方不加限定地访问它,不管是读还是写。
这可能不是一个好主意,考虑将其声明为Private,并且只将其公开为Public Property Get,以便它在任何时候、任何地方都 * 不能 * 被任何东西覆盖。
如果它是ThisWorkbook中的Public,这应该可以工作:

Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)
    Set ThisWorkbook.wsWorking = ThisWorkbook.Worksheets("MRL 1")
    Dim clickRow As Integer '<~ this will explode at row 32,768. Use a Long!
    Dim ClickCol As Integer '<~ should still be a Long

这里有几个严重的问题:

Call SaveFormToScorecard_Click '<~ event handlers aren't supposed to be invoked like this
    Unload Me '<~ self-destructing object, danger!
    ActiveWorkbook.Sheets(wsWorking).Activate '<~ will throw error 1004 End Sub ```

ActiveWorkbook是 * 任何工作簿碰巧在那个时候是活动的 *,虽然它 * 可能是 * ThisWorkbook,但也有很大的可能不是。无论何时它不是,这个 * 都会 * 崩溃。wsWorkingWorksheet引用,取消引用它是多余的(通过名称,隐式地!)从Sheets集合中-只需要ThisWorkbook.wsWorking.Activate就可以了。
注意,如果wsWorking在编译时存在于ThisWorkbook中,那么最好使用它自己的预声明示例。
每个Worksheet模块都有一个(Name)属性,该属性是VB项目组件的名称;这个值变成了一个全局对象的名字,就像ThisWorkbook一样。2更多的信息请参考implicit containing workbook reference Rubberduck inspection。

相关问题