Pozdrawiam
Radek
--
Wysłano z serwisu OnetNiusy: http://niusy.onet.pl
> ... Czy jest na to jakiś
> sposób?
F1("kolekcja Errors")
Ciao, Smyk
--
Fju fju - powiedział Ćwirek
Nie wiem czy zostałem dobrze zrozumiany, ale mnie udało się przechwycic błąd
ODBC (3156 jeśli dobrze pamietam)-problem w tym
że ten błąd zwraca wiele różnych zdarzeń, a nie tylko powtórzenie w kluczu.
W związku z tym nie mogę rozróznić co było przyczyną.
> Nie wiem czy zostałem dobrze zrozumiany, ...
Przeczytales ? Chyba nie skoro dalej pytasz. Eh ^k.{4}$ !
Otoz w momencie wystapienia bledu, kolekcja Errors wypelniana jest
przynajmniej jednym objekten Error. Takich bledow moze jednak byc wiecej.
W przypadku ODBC mozna tam znalezc najczesciej 3 Error'y.
Pierwszy - zwracany domyslnie - to wlasnie ow "Nieudane wywołanie ODBC".
Drugi zwracany przez warstwe menadzera zrodel ODBC a trzeci od wlasciwego
sterownika ODBC. Jesli sterownik ODBC oparty jest na natywnych bibliotekach
danego silinka (np. "ORACLE OCI" lub "Sybase OpenClient") moze byc jeszcze
czwarty Error, pochodzacy wlasnie od tej warstwy.
W przypadku bledu wartosci dla klucza/indexu, obawiam sie, ze
warstwa menadzera zrodel ODBC zwroci cos na ksztalt "Integrity constraint
violation" albo "General error". Wtedy trzeba bedzie siegnac glebiej
po trzeci albo nawet po czarty Error.
Blazek
Po krótkim zapoznaniu się myslałem że to nie to, ale jeśli tam są jakieś
poziomy to już się zabieram do pracy.
Dzięki
Przeczytałem, potestowałem i stwierdzam, że mam tylko jeden błąd w kolekcji
dotyczący ODBC. Wydaje mi się, że musiałbym mieć założony Workspace (dbUseODBC)
a ja mam formularz oparty o tabelę połączoną (przez ODBC do MSSQL, Acc 97). Czy
w takim przypadku da się wydobyc komunikat o błędzie (prawdopodobnie zwracany
przez sterownik do bazy)?
Pozdrawiam
> Przeczytałem, potestowałem i stwierdzam, że mam tylko jeden błąd w
> kolekcji dotyczący ODBC. Wydaje mi się, że musiałbym mieć założony
> Workspace (dbUseODBC) a ja mam formularz oparty o tabelę połączoną
> (przez ODBC do MSSQL, Acc 97).
To nie ma nic wspolnego z dbUseODBC. Dziala takze w kombinacji z
Jet'em. Sam sie kiedys na to zlapalem.
> Czy w takim przypadku da się wydobyc komunikat o błędzie
> (prawdopodobnie zwracany przez sterownik do bazy)?
Mozesz przytoczyc kod, ktorym sprawdzasz bledy ?
Ciao, Smyk
--
Fju, fju - powiedział Ćwirek
Oczywiście:
Dim liczerr as integer
On Error Resume Next
err.Clear
Errors.Refresh
Debug.Print Errors.Count
For Each liczerr In DBEngine.Errors
Debug.Print liczerr.Description
Debug.Print liczerr.Source
Debug.Print liczerr.Number
Debug.Print err.Description
Debug.Print err.Source
Debug.Print err.Number
Next liczerr
To mi zwraca jeden błąd w kolekcji.
Ponizej przekleilem fragment dzialajacego kodu z Accessa 97, ktory poprzez
ODBC korzysta z MsSql. Czyli Twoj przypadek... I to dziala:
Set Rs = SbF.RecordsetClone
Rs.AddNew
Rs!Lp = Rs.RecordCount + 1
Rs!DowNag = Me!DowNag
Rs.Update
If Err <> 0 Then
For i = DBEngine.Errors.Count - 1 To 0 Step -1
Set errX = Errors(i)
MsgBox errX.Description, 48
Next i
End If
Przyklad wyswietla wszystkie bledy z kolejki, nie tylko jeden ostatni. Moze
ten przyklad Ci pomoze... W sumie nie piszesz najwazniejszego - jak
aktualizujesz te tabele? Trudno, zebys tu zamieszczal caly swoj kod, ale
moze sprobujesz powyzszego sposobu? Jesli do aktualizacji bazy nie uzywasz
metod DAO, to i nie bedziesz mial bledow DAO w kolekcji DBEngine.Errors.
Krzysztof Pozorek
Set db = OpenDatabase("SQL", False, False, "ODBC;DRIVER=SQL
Server;SERVER=SQLSRV1...)
Set rst = db.OpenRecordset("Select * from klienci", dbOpenDynaset)
rst.AddNew
rst("id") = 55
rst("nr") = 414124
rst("ex") = 0
rst("ed") = 0
rst.Update
Err_Polecenie18_Click:
If err <> 0 Then
For i = DBEngine.Errors.Count - 1 To 0 Step -1
Set errx = Errors(0)
msgbox errx.Description, 48
a = err.Number
Next i
End If
**************************************************************
Potem zrobiłem z taką obsługą (znalazłem to na grupie lub w helpie)
Err_Polecenie18_Click:
' Wylicz elementy kolekcji Errors i wyświetl
' właściwości każdego obiektu Error.
For Each errPętla In Errors
With errPętla
strblad = "Nr błędu: " & .Number & vbCr
strblad = strblad & _
" " & .Description & vbCr
strblad = strblad & _
" (Źródło: " & .Source & ")" & vbCr
strblad = strblad & _
"Naciśnij F1, aby obejrzeć " & _
"temat Pomocy " & .HelpContext & vbCr
strblad = strblad & _
" zamieszczony w pliku " & _
.HelpFile & "."
End With
msgbox strblad
Next
i to zwraca mi błąd 2627 - i to jest chyba błąd oznaczjący powtórzenie w
kluczu.
**************************************************************
Ale za nic nie mogę uzyskać tego na formularzu opartym na tabeli połączonej.
>> Mozesz przytoczyc kod, ktorym sprawdzasz bledy ?
> Oczywiście:
>
> Dim liczerr as integer
> [...]
Przecwiczylem to jeszcze raz i okazuje sie, ze uzywajac ADOBD
Zawsze otrzymuje tylko jeden blad w kolekcji - "ODBC - call failed".
Nie testowalem co bedzie w przypadku, jesli otworzymy jawnie polaczenie
do zrodla ODBC. W watku chodzi o obsluge bledu w formularzu wspopracujacym
z podlinkowana tabela - zatem DAO. Biblioteka DAO jest bardziej rozmowna.
Ponizsza peocedurka zwrwaca nastepujace bledy:
MSSQL:
Number : 3146
Description: ODBC--call failed.
Source : DAO.Recordset
-------
Number : 3621
Description: [Microsoft][ODBC SQL Server Driver][SQL Server]
Die Anweisung wurde beendet.
Source : ODBC.Recordset
-------
Number : 2601
Description: [Microsoft][ODBC SQL Server Driver][SQL Server]
Zeile mit doppeltem Schluessel kann in Objekt 'xxx'
mit eindeutigem Index 'xxx_PrimaryKey' nicht eingefuegt
werden.
Source : ODBC.Recordset
(nie chce mi sie tlumaczyc meldunkow :-) )
ORACLE
Number : 3146
Description: ODBC--call failed.
Source : DAO.Recordset
-------
Number : 1
Description: [Oracle][ODBC][Ora]ORA-00001: unique constraint
(xxx.SYS_C004045) violated
Source : ODBC.Recordset
W formularzu najlepiej zdefiniowac obsluge bledu dla calego formualarza
(OnError). Mozna takze zaryzykowac w BeforeUpdate ale nie jestem pewnien
czy bedzie dzialac.
Ciao, Smyk
PS: Oto kod, ktorego uzylem (DAO)
-----------------------------8<------------------------------------
Sub TestDAOErrorsCollection()
On Error GoTo TestDAOErrorsCollection_Error
Dim rs As DAO.Recordset
Dim e As DAO.Error
Set rs = DBEngine(0)(0).OpenRecordset("xxx", _
dbOpenDynaset, _
dbAppendOnly)
rs.AddNew
rs!xxx_Index = 8
rs.Update
rs.Close
Set rs = Nothing
TestDAOErrorsCollection_Exit:
Exit Sub
TestDAOErrorsCollection_Error:
Dim i&
'-- "For Each" takze dziala ale pokazuje bledy w odwrotnej kolej.
For i = Errors.Count - 1 To 0 Step -1
Set e = Errors(i)
With e
Debug.Print "Number : " & .Number
Debug.Print "Description: " & .Description
Debug.Print "Source : " & .Source
Debug.Print "-------"
End With
Next i
Set e = Nothing
Resume TestDAOErrorsCollection_Exit
End Sub
> W formularzu najlepiej zdefiniowac obsluge bledu dla calego formualarza
> (OnError).
Sprawdzilem - chodzi. Jako "Response" najlepiej zwrocic acDataErrContunue
i wyswietlich wlany medunek bledu (lub obsluzyc go inaczej).
Ciao, Smyk
Tak, ale mnie intryguje dlaczego nie uzyskuję informacji o tych błedach mając
formularz oparty na kwerendzie i korzystając z metody zapisu w stylu:
DoCmd.DoMenuItem acFormBar, acRecordsMenu, acSaveRecord, , acMenuVer70
:-) No, nareszcie wyjawiles jak aktualizujesz te dane...
DBEngine.Errors dotyczy tylko bledow DAO. Twoja metoda DoCmd nie korzysta z
DAO, dlatego nie masz bledow w kolekcji.
K.P.
> Tak, ale mnie intryguje dlaczego nie uzyskuję informacji o tych błedach
> mając formularz oparty na kwerendzie i korzystając z metody zapisu w
> stylu:
>
> DoCmd.DoMenuItem acFormBar, acRecordsMenu, acSaveRecord, , acMenuVer70
A sprawdziles co siedzi w Err ?
Pamietasz co bylo napisane w helpie o kasowaniu kolekcji w przypadku
wykonywania innych funkcji _mogacych_ sprowokowac blad ? Byc moze
zmiana kontekstu wykonywanej operacji (formularz -> makro -> formularz)
to wlasnie taka operacja ?
Przerobiłem formularz żeby działał zgodnie ze sztuką (źródło danych jako
DAO.recordset) i działa ta obsługa błędów faktycznie. Formularz oparty na
kwerendzie to jednak ułomne rozwiazanie-nie udało mi się przy takim rozwiązaniu
wydobyć błędu powtórzenia w kluczu.
Dziękuje