'Frmmain窗体
Option Explicit
Dim tStudents As Students
Dim tStudent As StudentPrivate Sub CmdDel_Click()
On Error GoTo HandleError
    Dim tKey As String
    tKey = InputBox("请输入要删除学生的学号:", "删除学生")
    If tKey <> Empty Then
        tStudents.Remove tKey
        MsgBox "删除成功!", vbInformation + vbOKOnly, App.Title
    End If
Exit Sub
HandleError:
    MsgBox Err.Description, vbInformation + vbOKOnly, App.Title
End SubPrivate Sub CmdSave_Click()
On Error GoTo HandleError
    '看看这里,不重新实例化对象就会在集合中Add中出错。
    'Set tStudent = New Student
    With tStudent
        .No = TxtNo.Text
        .Name = TxtName.Text
        .Sex = IIf(TxtSex.Text = "男", True, False)
    End With
    tStudents.Add tStudent
    MsgBox "保存成功!", vbInformation + vbOKOnly, App.Title
    Me.Caption = "共有" & tStudents.Count & "个学生"
Exit Sub
HandleError:
    MsgBox Err.Description, vbInformation + vbOKOnly, App.Title
End SubPrivate Sub CmdView_Click()
On Error GoTo HandleError
    Dim ttstudent As New Student
    PicView.Cls
    PicView.Print "学号" & Space(2) & "姓名" & Space(2) & "性别" & vbCrLf
    For Each ttstudent In tStudents
        With ttstudent
            PicView.Print .No & Space(2) & .Name & Space(2) & IIf(.Sex = True, "男", "女") & vbCrLf
        End With
    Next
Exit Sub
HandleError:
    MsgBox Err.Description, vbInformation + vbOKOnly, App.Title
End Sub
Private Sub Form_Load()
     Me.Caption = "共有0个学生"
    Set tStudent = New Student
    Set tStudents = New Students
End SubPrivate Sub Form_Unload(Cancel As Integer)
    Set tStudent = Nothing
    Set tStudents = Nothing
End Sub'Student类模块
Option Explicit
Private sNo As Integer
Private sName As String
Private sSex As Boolean
Enum StudentError
    StudentErrorNo = vbObjectError + 512 + 1
    studenterrorname = vbObjectError + 512 + 2
End Enum
Property Let No(ByVal intNo As Integer)
    If intNo > 0 Then
        sNo = intNo
    Else
        Err.Raise StudentErrorNo, "Student", "学号必须大于零。"
    End If
End PropertyProperty Get No() As Integer
    No = sNo
End PropertyProperty Let Name(ByVal StrName As String)
    If StrName <> Empty Then
        sName = StrName
    Else
        Err.Raise studenterrorname, "Student", "姓名不能为空。"
    End If
End Property
Property Get Name() As String
    Name = sName
End PropertyProperty Get Sex() As Boolean
    Sex = sSex
End PropertyProperty Let Sex(ByVal BoolSex As Boolean)
    sSex = BoolSex
End PropertyPublic Sub ShowInfo(tNo As Integer, tName As String, tSex As Boolean)
    tNo = sNo
    tName = sName
    tSex = sSex
End Sub
'Students类模块Option Explicit
Private tStudents As Collection
Public Enum StudentsError
    StudentsErrorAdd = vbObjectError + 512 + 1
    StudentsErrorRemove = vbObjectError + 512 + 2
    StudentsErrorItem = vbObjectError + 512 + 3
End Enum
Private Sub Class_Initialize()
    Set tStudents = New Collection
End SubPrivate Sub Class_Terminate()
    Set tStudents = Nothing
End SubPublic Sub Add(ByVal tStudent As Student)
On Error GoTo HandleError
    tStudents.Add tStudent, Trim(Str(tStudent.No))
Exit Sub
HandleError:
    Err.Raise StudentsErrorAdd, "Students", "学号不能重复!"
End SubPublic Sub Remove(ByVal tKey As String)
On Error GoTo HandleError
    tStudents.Remove tKey
Exit Sub
HandleError:
    Err.Raise StudentsErrorRemove, "Students", "要删除的学生不存在。"
End SubPublic Function Item(ByVal tKey As String) As Student
On Error GoTo HandleError
    Set Item = tStudents.Item(tKey)
Exit Function
HandleError:
    Err.Raise StudentsErrorItem, "Students", "没有学号为" & tKey & "的学生。"
End FunctionPublic Property Get Count() As Long
    Count = tStudents.Count
End PropertyPublic Function NewEnum()
    Set NewEnum = tStudents.[_NewEnum]
End Function

解决方案 »

  1.   

    定义的时候实例化Option Explicit
    Dim tStudents As New Students
    Dim tStudent As New Student
      

  2.   

    Private Sub Form_Load()
         Me.Caption = "共有0个学生"
        Set tStudent = New Student
        Set tStudents = New Students
    End Sub在这里已经实例化过了。
    并非是对象没有实例化,而是每次调用集合类的add方法的时候,会覆盖集合中原来的对象元素。
    除非每传入对象前都Set tStudent = New Student,就没有问题了。请高手指点问题的原因。
      

  3.   

    原程序下载:
    http://www.jxtdtc.com/ShuMM/stu.rar在线等高手指教!谢谢!
      

  4.   

    集合类的add方法只是添加对某个对象的引用,并不是复制
    所以在每次调用add方法前都得New出一个新对象
      

  5.   

    VB对象机制是基于COM的
    所以也继承了COM的引用计数机制
    VB中的对象变量实际上只是一个指针每次给对象变量赋值时(Set objB = objA)
    并不是复制objA中的内容到objB
    而是让objB也引用objA指向的对象
      

  6.   

    那Set objB = New objA
    是不是objB就不再是objA的引用了?
      

  7.   

    Set objB = New objA
    表示objB指向一个新创建的objA型对象
      

  8.   

    完整的例子
    '权限
    Private Const AccessA As Long =  &H1
    Private Const AccessB As Long =  &H2
    Private Const AccessC As Long =  &H4
    Private Const AccessD As Long =  &H8
    Private Const AccessE As Long = &H10
    Private Const AccessF As Long = &H20
    '……dim MyP as Long '我的权限'赋予AccessC权限
    MyP = MyP or AccessC'判断是否拥有AccessC权限
    If MyP And AccessC Ten
        '拥有AccessC权限
    End If
      

  9.   

    那Set objB = New objA
    是不是objB就不再是objA的引用了?仍然是引用。第一个引用。B的内容是个地址。
      

  10.   

    正想学自定义类做usercontrol控件
    找了好久,终于找到了
    ,谢谢楼主啦
      

  11.   

    关于集合类的写法。
    http://community.csdn.net/Expert/topic/4625/4625394.xml?temp=.5268976
      

  12.   

    '看看这里,不重新实例化对象就会在集合中Add中出错。
    ---------------------------------
    集合ADD方法增加的只是一个对象指针,如果不重新实例化的话,就会出现引用同一个对象的情况,这对于集合类是不允许。