Vba 关闭工作簿会破坏变量吗?

Vba 关闭工作簿会破坏变量吗?,vba,excel,Vba,Excel,我定义了一个名为“cSettings”的类。然后我创建了一个名为“info”的cSettings对象。info对象有一种方法,可以从用户选择的工作簿中读取数据,然后将其存储在其成员变量中。成员变量是对象类型。更具体地说,“嵌套字典”类型 我观察到的是-在关闭工作簿之前,info对象中的所有数据都是良好的。关闭工作簿后,当访问其中一个成员变量时,将显示“需要对象”消息。因此,似乎关闭工作簿以某种方式破坏了部分数据。但是怎么做呢?这是我的密码: ' Class module cSettings O

我定义了一个名为“cSettings”的类。然后我创建了一个名为“info”的cSettings对象。info对象有一种方法,可以从用户选择的工作簿中读取数据,然后将其存储在其成员变量中。成员变量是对象类型。更具体地说,“嵌套字典”类型

我观察到的是-在关闭工作簿之前,info对象中的所有数据都是良好的。关闭工作簿后,当访问其中一个成员变量时,将显示“需要对象”消息。因此,似乎关闭工作簿以某种方式破坏了部分数据。但是怎么做呢?这是我的密码:

' Class module cSettings

Option Explicit
Public obj1 As Object
Public obj2 As Object

' ----------

Public Sub ReadFrom(wb As Workbook)
    Set obj1 = CreateObject("Scripting.Dictionary")
    Set obj2 = CreateObject("Scripting.Dictionary")

    Set obj1 = Get1(wb, "sheet1")
    Set obj2 = Get2(wb, "sheet2")
End Sub

Private Function Get1(wb As Workbook, sh As String) As Dictionary
    Dim a_obj as object
    Set a_obj = CreateObject("Scripting.Dictionary")

    ' Read from workbook

    ' Add data to outer dictionary, creating inner dictionary
    a_obj.add "key1", CreateObject("Scripting.Dictionary")

    ' Add data to inner dictionary
    a_obj("key1").add "key11", "Value11"

    Set Get1 = a_obj
End Function

Private Function Get2(wb As Workbook, sh As String) As Dictionary
    Dim a_obj as object
    Set a_obj = CreateObject("Scripting.Dictionary")

    ' Read from workbook

    ' Add data to outer dictionary, creating inner dictionary
    a_obj.add "key2", CreateObject("Scripting.Dictionary")

    ' Add data to inner dictionary
    a_obj("key2").add "key21", "Value21"

    Set Get2 = a_obj
End Function
以下是主要节目:

Sub Main()
    Dim myFile As Variant
    Dim wb As Workbook
    Dim info As New cSettings

    myFile = Application.GetOpenFilename()
    Set wb = Workbooks.Open(myFile, False, True)

    info.ReadFrom wb

    Debug.Print info.Items("key1")("key11").count '<-- OK
    Debug.Print info.Items("key2")("key21").count '<-- OK

    wb.Close

    Debug.Print info.Items("key1")("key11").count '<-- OK
    Debug.Print info.Items("key2")("key21").count '<-- Error "Object Required"
End Sub
Sub-Main()
Dim myFile作为变量
将wb设置为工作簿
Dim信息作为新的C设置
myFile=Application.GetOpenFilename()
设置wb=Workbooks.Open(myFile,False,True)
info.readfromWB

Debug.Print info.Items(“key1”)(“key11”).count“您发布的代码未编译。经过一些修改以使其运行,我无法再现错误:

Sub Main()
    Dim myFile As Variant
    Dim wb As Workbook
    Dim info As New cSettings

    myFile = Application.GetOpenFilename()
    Set wb = Workbooks.Open(myFile, False, True)

    info.ReadFrom wb

    Debug.Print info.obj1("key1")("key11") '<-- OK
    Debug.Print info.obj2("key2")("key21") '<-- OK

    wb.Close

    Debug.Print info.obj1("key1")("key11") '<-- OK
    Debug.Print info.obj2("key2")("key21") '<-- OK
End Sub
Sub-Main()
Dim myFile作为变量
将wb设置为工作簿
Dim信息作为新的C设置
myFile=Application.GetOpenFilename()
设置wb=Workbooks.Open(myFile,False,True)
info.readfromWB
Debug.Print info.obj1(“key1”)(“key11”)’好的,我想出来了

在我的代码中,我使用
dictionary.Add
方法添加单元格内容。原始代码类似于
myDic.Add“key”,ws.cells(r,c)
,其中
ws
指的是打开的工作簿的工作表。作为一个新手,我认为它会获取单元格的值,然后简单地向字典中添加一个
键、值

实际上它所做的是添加一个指向该单元格的指针。当工作簿关闭时,当然该单元格将不再存在。因此,字典的内容被破坏了。我按如下所示更改了代码,并按预期工作:

val = ws.cells(r,c)
myDic.Add "key", val

新手问题:我如何告诉VB使用值而不是引用?谢谢

尝试将
info
声明为子例程外部的
Global
变量。@dwirony,谢谢您的帮助。我可以知道为什么信息需要声明为全局信息吗?为什么“信息”中的部分数据不见了,而不是全部?我会试试你的建议,然后再向你汇报。谢谢大家!@Helloguys一旦你到了End Sub,
info
就不在范围之内了,正如
myFile
wb
在模块级声明它们意味着其他Sub/function等仍然可以使用它们我不太明白。我只在
main()
sub中使用
info
,为什么要将其声明为全局?另外,
info
中的一些成员变量正常,但
info
中的其他一些成员变量已损坏/消失。我不明白有什么区别。只是尝试将
info
声明为全局。相同的错误。您修改了什么?
info.Items
无法编译,因此我将其更改为
info.obj1
info.obj2
.count
无法编译,因此我打印了字典值。可能您正在执行
myDic.Add“key”,ws.cells(r,c)
。使用
myDic.Add“key”,ws.cells(r,c).Value
instead@Chris非常感谢。作为一个新手,我总是忘记单元格(r,c)和单元格(r,c)之间的区别。值,因为它们通常返回“相同”的结果