VB6에서“객체 변수 또는 블록 변수가 설정되지 않음”런타임 오류

StackOverflow https://stackoverflow.com/questions/1206526

  •  05-07-2019
  •  | 
  •  

문제

VB6에 문제가 있습니다. 나는 그것에 몇 가지 combobox 객체가있는 양식이 있습니다. SQL 쿼리를 매개 변수로 취하는 함수를 통해 Comboboxes를 채우고 싶습니다. 따라서 코드는 다음과 같습니다

Private Function FillComboBoxFromMDB(ByVal sDBName As String, _
                                     ByVal sSQL As String) As ComboBox
    '/*
    ' * Execute SQL in MDB and fill the ComboBox with the results
    ' * Returns filled ComboBox
    ' */
    Dim DB As Database
    Dim DBRecordset As Recordset

    On Error GoTo FillComboBoxFromMDB_ErrHandler

    Set DB = OpenDatabase(sDBName, False, False)

    If Not DB Is Nothing Then
        Set DBRecordset = DB.OpenRecordset(sSQL)
        If Not DBRecordset Is Nothing Then
            If DBRecordset.RecordCount > 0 Then
                Call FillComboBoxFromMDB.AddItem(DBRecordset.Fields(0).Value)
                ' ^^ This row gives the "Object variable or With block variable not set"
            End If
        Else
            Call WriteLog("Unable to execute " & sSQL)
        End If
        DB.Close
    Else
        Call WriteLog("Unable to open " & sDBName)
    End If

    Exit Function
FillComboBoxFromMDB_ErrHandler:
    Call WriteLog("FillComboBoxFromMDB() error: " & Err.Number & " " & Err.Description)
End Function

나는 다음과 같은 기능을 부릅니다.

Private Function Test()
    ' Fill the combobox
    frmMyForm.cmbMyCombo = FillComboBoxFromMDB("Database.mdb", _
                                               "SELECT MyTable.MyText FROM MyTable")
End Function

기본적으로 나는 이것이 인스턴스화로 이어진다는 것을 이해하지만 온라인에서 유용한 것은 발견하지 못했습니다. 새로운 키워드는 vb.net에서 작동하는 것처럼 작동하지 않습니다. 기능이 작동하도록 FillComboBoxfrommdb combobox를 어떻게 인스턴스화합니까? 가능합니까?

미리 감사드립니다!

도움이 되었습니까?

해결책

코드는 식별자라는 신념을 표현합니다 FillComboBoxFromMDB 테스트 절차에서 과제의 왼쪽에서 Combobox에 대한 참조를 얻었습니다.

이 경우 기능이 FillCombboxFrommDB가 결과를 왼쪽에 할당하려고 시도하고 실패하면 기능이 먼저 실행되는 경우가 아닙니다.

Combobox를 매개 변수로 전달해야합니다.

Private Sub FillComboBoxFromMDB(ByVal sDBName As String, _
                                     ByVal sSQL As String, ByVal cbo As ComboBox)
    '/*
    ' * Execute SQL in MDB and fill the ComboBox with the results
    ' * Returns filled ComboBox
    ' */
    Dim DB As Database
    Dim DBRecordset As Recordset

    On Error GoTo FillComboBoxFromMDB_ErrHandler

    Set DB = OpenDatabase(sDBName, False, False)

    If Not DB Is Nothing Then
        Set DBRecordset = DB.OpenRecordset(sSQL)
        If Not DBRecordset Is Nothing Then
            If DBRecordset.RecordCount > 0 Then
                Call cbo.AddItem(DBRecordset.Fields(0).Value)
                ' ^^ This row gives the "Object variable or With block variable not set"
            End If
        Else
            Call WriteLog("Unable to execute " & sSQL)
        End If
        DB.Close
    Else
        Call WriteLog("Unable to open " & sDBName)
    End If

    Exit Sub
FillComboBoxFromMDB_ErrHandler:
    Call WriteLog("FillComboBoxFromMDB() error: " & Err.Number & " " & Err.Description)
End Sub

다음과 같이 부릅니다 :-

 Private Function Test()
 ' Fill the combobox
 Call FillComboBoxFromMDB("Database.mdb", _
                          "SELECT MyTable.MyText FROM MyTable", _
                          frmMyForm.cmbMyCombo ) 
 End Function

다른 팁

VB6 양식 컨트롤로 작업하는 데 문제가 있으면 양식으로 만 인스턴스화 할 수 있습니다. 어떤 끔찍한 말! 오 예, 당신은 컨트롤이 거주하는 DLL을 등록 할 수 있습니다. 재미있게 보내십시오! 나는 TCP/IP 소켓으로 이것을 달렸다.

내 솔루션은 Socketdriver 인터페이스를 만드는 것이 었습니다. 양식을 만들고 소켓을 양식에 넣습니다. 양식을 보이지 않게 만드십시오. 양식에서 Socketdriver 인터페이스를 구현하십시오. 이제 소켓 드라이버를 통과 할 수 있습니다.

나는 Anthony의 대답을 좋아합니다. 하나의 방법으로 'datafiller'라는 인터페이스를 만들었을 것입니다.

Public Sub AddItem(item As String)
End Sub

그런 다음 양식을 구현하십시오.

Public Sub AddItem(item As String)
   cmbMyCombo.AddItem(item)
End Sub

이제 서명을 사용하십시오

Private Sub FillComboBoxFromMDB(ByVal sDBName As String, _
                                 ByVal sSQL As String, ByVal injectWith As DataFiller)
   'yada yada code

   injectWith.AddItem(DBRecordset.Fields(0).Value)

   'yada yada code

End Sub

Private Function Test()
   ' Fill the combobox
   FillComboBoxFromMDB("Database.mdb", _
                                           "SELECT MyTable.MyText FROM MyTable", frmMyForm)
End Function

인터페이스를 사용하면 약간의 관심이 분리 될 수 있습니다. 귀하의 데이터 액세스는 양식 또는 컨트롤에 대해 아무것도 모르고 귀하의 Froms and Controls는 의존성이 인터페이스에있어서 해당 데이터가 어디에서 왔는지 모릅니다.

Q : additem을 호출하기 전에 FillComboBoxFrommDB가 무엇입니까?
A : 아무것도, 그것이 당신이 오류를 얻는 이유입니다

같은 변수를 정의하십시오

Dim Value as ComboBox

그런 다음 additem을 호출하십시오

Value.AddItem(...)

그런 다음 함수의 끝에 있습니다

FillComboBoxFromMDB = Value

또는 다른 대답으로 사용하려는 것처럼 리턴 유형을 사용하고 싶지 않은 경우.

리턴 유형이 ComboBox, 그러나 실제로 반환 값을 설정 한 곳은 어디에서나 볼 수 없습니다. 반환 값이 설정되지 않으므로 Nothing, 따라서 액세스 할 때 오류가 발생합니다.

당신이 공급하는 유스 케이스에서, 나는 당신이 원하는 것이 기존의 콤보 박스. 그래서 당신은 이것을 다음과 같이 부를 것입니다.

' Fill the combobox
FillComboBoxFromMDB(frmMyForm.cmbMyCombo, _
                    "Database.mdb", _
                    "SELECT MyTable.MyText FROM MyTable")

서브 루틴 자체는 다음과 같은 서명을 가질 것입니다.

private sub fillcomboboxfrommdb (combobox as byval cbo, _ byval sdbname as string, _ byval ssql as string)

(a입니다 Sub 아니에요 Function). 당신이 가진 서브 루틴의 몸 안에

 Call FillComboBoxFromMDB.AddItem(DBRecordset.Fields(0).Value)

대신

 cbo.AddItem(DBRecordset.Fields(0).Value)

행동하기 위해 ComboBox 그것은 서브 루틴으로 전달되었습니다.

나는 VB6에서 같은 문제에 직면했고 해결책도 발견했습니다.

문제의 이유는

저장된 절차에는 여러 개의 선택된 명세서가있었습니다.

해결책 : 나는 사용했다 SET NOCOUNT ON 저장 절차 시작시 SET NOCOUNT OFF 최종 선택 (출력) 문 직전.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top