vbamania.pl
login:
hasło:
 
  *Rejestracja *Zapomniane hasło
 Dziś jest poniedziałek, 07 lipca 2025 roku.
Ustaw jako stronę startową Ulubione Napisz
PowrótPowrót do serwisu  RegulaminRegulamin rssRSS

  tytuł wątku:
Wątki dyskusji

VBA Excel + SQL Access, import z Access.mdb do Excel.xlsm


otwartyotwarty rozpoczął: sisa postów: 4



napisał: jalamas
postów: 316


umieszczony:
11 sierpnia 2009
08:44

  
Sisa:
Mam takie uwagi
1. Podejrzewam, że nie masz Option Explicit, ponieważ wówczas kod by się poprawnie nie kompilował !
- brak deklaracji MyConn, lecz to mały problem
- AdForwardOnly - nie ma takiej stałej i kompilator by Ci to wskazał.
Przypuszczam, że miałeś na myśli adOpenForwardOnly.
Wartości tych stałych i innych zmiennych przy obsłudze bazy danych są bardzo istotne.

2. W zestawie:
CursorType:=adOpenForwardOnly, LockType:=adLockOptimistic
kursor po stronie servera i tak nie jest wcale adOpenForwardOnly tylko adOpenKeyset, podejrzyj sobie.
Musiałbyś użyć: CursorType:=adOpenForwardOnly, LockType:=adLockReadOnly.
Cytat:
When you select a CursorType that is not supported, the provider should select the CursorType...

Nie wiem, jaki masz powód, aby kursor był po stronie servera.
FinalRow = Range("A65536").End(xlUp).row, nawet z uwagą Rysia nie zawsze jest OK.
Zwłaszcza, gdy już coś do zakresu było wpisywane i nie tylko wtedy.

Ja bym wykorzystała: adUseClient, adOpenStatic, adLockReadOnly
Ponieważ CopyFromRecordset przesuwa na EOF, potem MoveLast i RecordCount.

3. O tym czy Recordset ma, że tak powiem rekordy, informuje:
If Not (Rst.BOF And Rst.EOF) Then


4. Przenigdy nie należy pomijać obsługi błędów, jeżeli sięgamy do bazy danych.
Grozi to pozostaniem pliku ldb (laccdb) - niemożnością ponownego otwarcia, a nawet uszkodzeniem bazy danych.
Nawet jeśli Bill takie przykłady prezentuje.

5. Jeśli już Set WSOrig = ActiveSheet to w obsłudze błędów musi być:
Set WSOrig = Nothing


6. Aby wpisywać do komórek nie trzeba "wachlować" Select ani Activate (tylko w wyjątkowych wypadkach jest to potrzebne)

7. Do procedury przekazałabym Range docelowe itd...

8. Polskie znaki...w nazwach się zemszczą...

P.S. Formalnie należałoby jeszcze sprawdzić czy mdb nie jest otwarta w trybie wyłączności przez innego usera, pominęłam...
W przybliżeniu tak:

Dim strMdbFullName As String
    strMdbFullName = Sciezka2Mdb & "\nazwa_pliku.mdb"
    Call ImportDanych(strMdbFullName, "1", Sheets("ark1").Range("A1"))

Option Explicit
Sub ImportDanych(ByVal MyConn As String, _
                 ByVal sID As String, _
                 Target As Excel.Range)
    On Error GoTo ImporDanyc_Error

    Dim Cnn As ADODB.Connection
    Dim Rst As ADODB.Recordset
    Dim sSQL As String
    Dim FinalRow As Long

    sSQL = "SELECT IDartykulu, nr_artykulu, Opis, Ilosc, Nr_atestu FROM nazwa_tabeli "
    sSQL = sSQL & " WHERE IDartykulu=" & sID
   ' Call ScreenCalcEvents(False)
    Set Cnn = New ADODB.Connection
    With Cnn
        .Provider = "Microsoft.Jet.OLEDB.4.0"
        .CursorLocation = adUseClient
        .Open MyConn
    End With
    Set Rst = New ADODB.Recordset
    With Rst
        .CursorType = adOpenStatic
        .LockType = adLockReadOnly
        Set .ActiveConnection = Cnn
        .Open sSQL, , , , adCmdText
        FinalRow = 1
        Target.Cells(1, 1).Resize(, 5) = Array("ID", "Nr artykułu", "Opis", "Ilość", "Nr atestu")
        If Not (.BOF And .EOF) Then    ' to jest info ze nie ma Recs
            Target.Cells(1, 1).Offset(1, 1).CopyFromRecordset Rst
            .MoveLast        ' bo jest EOF
            FinalRow = .RecordCount
        End If
        .Close
    End With
    Set Rst = Nothing
    Cnn.Close
    Set Cnn = Nothing
    If FinalRow = 1 Then
        ' ....
        MsgBox "Brak danych"
    Else
        MsgBox FinalRow
    End If

    '---------------------
ImporDanyc_Exit:
    On Error Resume Next
    Call CloseRSObject(Rst)
    Call CloseRSObject(Cnn)
    ' Call ScreenCalcEvents(True)
    Exit Sub

ImporDanyc_Error:
    MsgBox "Błąd : ( " & Err.Number & " ) " & Err.Description & vbCrLf & _
           "Procedura : " & "ImporDanyc", vbExclamation
    Resume ImporDanyc_Exit
End Sub

'--------------------------------------------
Public Sub CloseConObject(Cnn As ADODB.Connection)
    On Error Resume Next
    If Not (Cnn Is Nothing) Then
        If Cnn.State = adStateOpen Then Cnn.Close
        Set Cnn = Nothing
    End If
End Sub

Public Sub CloseRSObject(Rs As ADODB.Recordset)
    On Error Resume Next
    If Not (Rs Is Nothing) Then
        With Rs
            If CBool(.State And adStateOpen) Then
                If .EditMode <> adEditNone Then .CancelUpdate
                .Close
            End If
        End With
        Set Rs = Nothing
    End If
End Sub

Public Sub ScreenCalcEvents(Optional ByVal bTrue As Boolean)
    On Error Resume Next
    With Application
        If bTrue Then
            .EnableEvents = True
            .Calculation = xlCalculationAutomatic
            .ScreenUpdating = True
        Else
            .ScreenUpdating = False
            .Calculation = xlCalculationManual
            .EnableEvents = False
        End If
    End With
End Sub

napisał: sisa
postów: 2


umieszczony:
4 sierpnia 2009
15:34

  
Działa :)
Wielkie dzięki.
napisał: Rycho
postów: 291


umieszczony:
4 sierpnia 2009
13:28

  
Hej,
jeżeli wymaga by wartość "1" jest w arkuszu o nazwie 'Arkusz1' w komórce 'A1', to:
sSQL = sSQL & " WHERE ID=" & worksheets("Arkusz1").range("A1")

napisał: sisa
postów: 2


umieszczony:
4 sierpnia 2009
09:12

  
Witam.

Mam problem z kodem VBA Excel który ma importować dane z pliku .mdb do pliku .xlsm
Kod poniżej jest składanką zmodyfikowanych przykładów z książki i tego co udało mi się znaleźć w internecie i odziwo działa.
Dane po kryteriach ..."WHERE ID=1" są prawidłowo pobierane z Access.mdb do Excel.xlsm
Jednak program który usiłuje napisać wymaga by wartość "1" z ...WHERE ID=1" była ściągana z określonej komórki w arkuszu Excel
(zmieniając wartość w określonej komórce zmieniam kryteria wyboru danych do importu).
Próbowałem rozwiązać problem deklarując zmienną "xxx" która wskazywała adres do komórki i zamiast "1" wstarić "xxx" (..." WHERE ID:=xxx")
jednak nie udało się (brak wartości dla jednego lub kilku parametrów z linii rst.Open Source:=sSQL, ActiveConnection:=cnn,...)
Bardzo proszę o pomoc, mojej wiedzy za mało by ruszyć dalej.




Sub ImportDanych()


Dim cnn As ADODB.Connection
Dim rst As ADODB.Recordset
Dim WSOrig As Worksheet
Dim sSQL As String
Dim FinalRow As Long

Set WSOrig = ActiveSheet

'Utworzenie ciągu SQL w celu pobrania rekordów
sSQL = "SELECT ID, Nr_artykułu, Opis, Ilość, Nr_atestu FROM nazwa_tabeli"
sSQL = sSQL & " WHERE ID=1"

MyConn = "C:\Documents and Settings\rafal\Pulpit\nazwa_pliku.mdb"

Set cnn = New ADODB.Connection
With cnn
.Provider = "Microsoft.Jet.OLEDB.4.0"
.Open MyConn
End With


Set rst = New ADODB.Recordset
rst.CursorLocation = adUseServer
rst.Open Source:=sSQL, ActiveConnection:=cnn, CursorType:=AdForwardOnly, LockType:=adLockOptimistic, Options:=adCmdText


'wskazanie arkusza w którym ma być zapisany raport
Sheets("ark1").Select

'dodanie nagłówków
Range("A1:E1").Value = Array("ID", "Nr artykułu", "Opis", "Ilość", "Nr atestu")

'skopiowanie danych z zestawu rekordów do drugieo wiersza
Range("A2").CopyFromRecordset rst

'zamknięcie połączenia
rst.Close
cnn.Close

'sformatowanie raportu
FinalRow = Range("A65536").End(xlUp).Row

'Zatrzymanie procedóry jeśli zapytanie nie zwróciło żadnych rekordów
If FinalRow = 1 Then
' Application.DisplayAlerts = False
' WSTemp.Delete
' Application.DisplayAlerts = True
WSOrig.Activate
MsgBox "Brak danych"
Exit Sub
End If


End Sub


<-wstecz  1  dalej->
wszystkich stron: 1


Sortuj posty: z