vbamania.pl
login:
hasło:
 
  *Rejestracja *Zapomniane hasło
 Dziś jest piątek, 17 maja 2024 roku.
Ustaw jako stronę startową Ulubione Napisz
PowrótPowrót do serwisu  RegulaminRegulamin rssRSS

  tytuł wątku:
Wątki dyskusji

ADO z Excel do Excel dziwne zjawsko


otwartyotwarty rozpoczął: WojMak postów: 12



napisał: WojMak
postów: 7


umieszczony:
5 września 2007
18:27

edytowany:
5 września 2007
18:52

  
Mój program ma działać tak, żeby nikt nie wiedział o co chodzi, ba, żeby nie wiedział, że coś jest zapisywane - poprostu, kiedy będzie trzeba otworzy sobie plik stanowiący rejestr i dowie się co chce. Nikt nic nie poprzestawia, bo dostęp standardowo chronie hasłem (raczej ze wstydu niż ze względów bezpieczeństwa). Nie wiem jak u Ciebie w firmie ale u mnie nie można robić co się chce, bo dostęp jest ograniczony, a nad wszystkim czuwają pracownicy działu informatycznego i nawet jak ktoś coś usunie to jest to ich problem - odzyskają co utracone. U mnie w pracy jest tylko kilka osób takich jak ja,a więc obawy o grzebanie nie ma.

Niemniej zachęcony dopingiem z Twojej strony doczytałem jak sprawdzić wersje ADO i zrobiłem tak:

Private Function ADOVersion()
    Dim cn As New ADODB.Connection
    Set cn = New ADODB.Connection
    ADOVersion = cn.Version
End Function



Rozumiem, że wedle Twojej sugestii, gdyby było mniej niż 2.5 program stop i komunikat?

Wojciech
napisał: jalamas
postów: 316


umieszczony:
2 września 2007
23:49

  
Wiem kotek, że wiesz co to jest EOF i BOF, chciałam tylko abyś doczytał szczegóły "kiedy co", jeśli tak symbolicznie mogę się wyrazić...
Cytat:
a w niej wszyscy maja jednakowe wersje oprogramowania
ta... wszakże pod warunkiem, że nie masz takiego usera jak ja... który może co chce...
albo się mu "cóś" poplątało (tak jak mojemu koledze, który usuwa z kompa co popadnie doświadczalnie i czeka na efekty),
powinien mieć info, że nie jest w porzo...
I to nie jest wydumana sytuacja, moi userzy robią różne rzeczy....
Więc co Ci szkodzi ... przewidzieć i to, to tylko kilkanaście linni kodu...
Skoro już jesteś tak daleko...

Ciągle dopingująca
Blondynka...
napisał: WojMak
postów: 7


umieszczony:
1 września 2007
09:11

  
Wiem co to EOF and BOF, a z załączonego linka oczywiście skorzystam, bo jest tam kilka ciekawych rzeczy. Z późnym wiązaniem także się zetknąłem (wysyłanie emaili z poziomu Excela czy Accessa). W moim wypadku nie ma obawy o wersje ADO, bo działam w warunkach firmy, a w niej wszyscy maja jednakowe wersje oprogramowania. Ponadto oba pliki będą umieszczone na dysku sieciowym, a więc będę miał pełną kontrolę.

Jeszcze raz dziękuję za pomoc i cenne wskazówki.

Wojciech
napisał: jalamas
postów: 316


umieszczony:
31 sierpnia 2007
20:26

  
Słuszna uwaga, dzięki, powinno być:
If Not (.BOF And .EOF) Then  ' czy są rekordy (krotki, br...)


sorry wielkie, wyjaśnienie EOF i BOF tutaj:
http://www.w3schools.com/ado/prop_rs_bofeof.asp
albo, na pewno masz Access, więc:

Microsoft Access:
- okienko edycji bazy danych
- Menu/Pomoc
- zakładka Spis Treści
- punkt Obiekty Microsoft ADO (ActiveX Data Objects)
- podpunkt Microsoft ActiveX Data Objects (ADO)
- podpunkt Microsoft ADO Programmer's Reference
- podpunkt ADO API Reference
- podpunkt ADO Properties
- BOF, EOF Properties
i to chyba będzie dla Ciebie najwygodniejszy help, z przykładami, aczkolwiek niekoniecznie zawsze dobrymi.

Późne wiązanie (CreateObject) chociaż jest wolniejsze, lecz daje taką korzyść, że nie wiąże nas (naszej aplikacji) z wersją ADO ( np. 2.1, czy 2.5- default dla Win XP, 2.8).
Zresztą dotyczy nie tylko ADO.
Pozwala wykorzystać najnowszą wersję ADO, istniejącą na kompie.
Jest to istotne, gdy przenosimy naszą aplikację na inny komp popularnie mówiąc "do kolegi".
Nie mamy info, jaka wersja jest na tym innym kompie.
Jeśli nie skorzystamy z późnego wiązania
- może się zdarzyć, że nasza aplikacja nie będzie pracowała
- wówczas należałoby robić instalkę.

Ale i tak trzeba sprawdzać wersję Jet (powinna być 4.0, czyli ADO 2.1 i wyżej), ponieważ Jet 3.51 nie umożliwia korzystania z mdb w wersji 2000, np.
Tak naprawdę ja bym się domagała wersji, co najmniej 2.5.
To tak pokrótce...

Jeszcze raz dzięki za słuszne spostrzeżenie.
napisał: WojMak
postów: 7


umieszczony:
31 sierpnia 2007
19:56

  
Kod chcę wykorzystać do zapisu danych do pliku na dysku sieciowym, więc odpowiedni reference samodzielnie podepnę. Czy w związku z tym ma znaczenie to co napisałeś w ostatnim poście?

Kod, który napisałeś będzie najbardziej przydatny w zakresie dodania jednego rekordu chcę dodawać jeden rekord do pliku, który nazwałem new.xls podczas pracy z innym plikiem. Skoro jednak jesteśmy przy temacie pozwolę sobie zadać jeszcze jedno pytanie odnośnie kodu:

If Not (.BOF And .BOF) Then

dlaczego jest dwa razy .BOF? Wstyd się przyznać ale nie rozumiem, a nie chciałbym w przyszłości bezmyślnie przepisywać.

Wojciech
napisał: jalamas
postów: 316


umieszczony:
29 sierpnia 2007
21:25

  
WojMak, załączony kod nie obejmuje jeszcze sprawy takiej, że powinno być poźne wiązanie+ CreateObject, bez referencji ze sprawdzeniem tylko, że na kopie jest jest Jet 4... i to dopiero będzie " w miarę" całość.
napisał: jalamas
postów: 316


umieszczony:
29 sierpnia 2007
21:24

  
WojMak, załączony kod nie obejmuje jeszcze sprawy takiej, że powinno być poźne wiązanie, bez referencji ze sprawdzeniem tylko, że na kopie jest jest Jet 4... i to dopiero będzie " w miarę" całość.
napisał: WojMak
postów: 7


umieszczony:
28 sierpnia 2007
18:39

  
Wielkie dzięki za wyczerpujące wyjaśnienia oraz cierpliwość do moich błędów - załączony kod wymaga ode mnie wnilkiwej analizy, bo, przyznaje, nie ze wszystkim się zetknąłem w mojej krótkiej pracy z VBA.
Jeszcze raz dziękuje.

Wojciech
napisał: jalamas
postów: 316


umieszczony:
27 sierpnia 2007
17:17

edytowany:
31 sierpnia 2007
20:27

  
Cytat:
Otóż, w pliku new.xls w pierwszym wierszu w komórkach od A1 do A4 !!!!!! umieściłęm 4 nazwy tj Pole1, Pole2,Pole3,Pole4

Właśnie, już 2-gi raz piszesz to samo.
Rzeczywistość jest inna, ponieważ w Twoim xls nazwy Pole1, Pole2,Pole3,Pole4 są umieszczone w 1-szym wierszu, w komórkach A1:D1 !!!!
A jest to istotna różnica, pola , rekordy (krotki) nie sądzisz?.
Stąd moje zdziwienie.

W Twoim zapytaniu traktujesz cały arkusz jako tabelę.

Formuły itd... i nawet formatowanie wpisane gdziekolwiek w arkuszu wówczas też jest traktowane jak wypełniona komórka (chyba, że jest to formatowanie warunkowe).
Do rekordów w przypadku traktowania do arkusza jak tabeli, zaliczane są też wiersze, gdy komórki z innych kolumn są wypełnione. Na przykład w H40 niech będzie pogrubiony font.
Wówczas wiersz będzie wierszem tabeli i poprzedzające puste też.

Wyczyszczenie zawartości komórek wiersza nie jest tym samym, co usunięcie rekordu w tabeli, jest po prostu wpisaniem nowej wartości do pól rekordu.
Usunięcie rekordu w tabeli - arkuszu Excela odpowiada usunięciu wiersza, albo, jeśli to są wiersze końcowe, zaznaczeniu wierszy i wybraniu opcji "Usuń wszystko".
To mniej trochę analogiczne do tego:
Zdefiniuj nazwę:

moja_nazwa=Arkusz1!$A$1:$D$14

Wyczyść zwartość komórek w wierszu 4 - opcja Wszystko, zobacz czy definicja nazw się zmieniła.
Wyczyść zwartość komórek w wierszu 14 - opcja Wszystko, zobacz czy definicja nazw się zmieniła

Usuń komórki A14do D14 (przesuń w lewo) i zobacz czy definicja się zmieniała... itd ...

W Twoim arkuszu UsedRange jest A1:D22
Zatem Twój Rst ma widzę 21-den rekordów, ponieważ default jest HDR=YES.

Jet nie umożliwia usuwania rekordów w tabeli - Excelu.
Jedyną możliwością jest wyczyszczenie wartości pól, odnalezienie pustych rekordów na końcu wypełnienie ich, na temat typów przeczytaj:

http://support.microsoft.com/kb/q257819/

Może tak (nie wiem dokładnie, co ma być w docelowym arkuszu i do czego on służy), być może aż takie kombinacje są nie potrzebne:

Option Explicit

Public Sub WriteIntoExcel(ByVal sPathFileXls As String)
    On Error GoTo WriteIntoExcel_Error

    Dim Cn As ADODB.Connection
    Dim Rst As ADODB.Recordset
    Dim strQuery As String
    Dim i As Long
    Dim bEmptyRec As Boolean
    Dim FieldsList As Variant
    Dim FieldsValues As Variant
    Dim varBookmark As Variant

    FieldsList = Array(0, 1, 2, 3)
    FieldsValues = Array("wpis1", "wpis2", "wpis3", CStr(Time))

    Set Cn = New ADODB.Connection
    With Cn
        .Provider = "Microsoft.Jet.OLEDB.4.0"
        .ConnectionString = "Data Source=" & sPathFileXls & _
                            ";Extended Properties=""Excel 8.0;HDR=YES"";"
        .Open
    End With

    strQuery = "SELECT pole1,pole2,pole3,pole4 FROM [Arkusz1$]"     ' "SELECT * FROM [Arkusz1$]"
    Set Rst = New ADODB.Recordset
    With Rst
        .CursorLocation = adUseServer
        .CursorType = adOpenKeyset
        .LockType = adLockOptimistic
        .Open strQuery, Cn
        ' na clonie mozna tez szukac i bookmark na bookmark
        If Not (.BOF And .EOF) Then ' poprawione po uwadze Wojtka w poscie powzej
            .MoveLast
            Do While Not .BOF
                bEmptyRec = True
                For i = 0 To .Fields.Count - 1
                    If Len(Trim(.Fields(i).Value & "")) <> 0 Then
                        bEmptyRec = False
                        Exit For
                    End If
                Next
                If bEmptyRec = False Then Exit Do
                varBookmark = .Bookmark
                .MovePrevious
            Loop
        End If
        i = 0
        ' przypusmy chce dodac 4-ry rekordy
        Dim lNewNumber As Long
        lNewNumber = 4
        If Not IsEmpty(varBookmark) Then
            .Bookmark = varBookmark
            Do While Not .EOF And i < lNewNumber
                .Update FieldsList, FieldsValues
                i = i + 1
                MsgBox "Update " & CStr(i)
                .MoveNext
            Loop
        End If
        Do While i < lNewNumber
            .AddNew FieldsList, FieldsValues
            i = i + 1
            MsgBox "Addnew " & CStr(i)
        Loop
        ' w przypadku gdy tylko 1-den rekord dodajesz wystarczy
        ' If Not IsEmpty(varBookmark) Then
        ' .Bookmark = varBookmark
        ' .Update FieldsList, FieldsValues
        ' Else
        ' .AddNew FieldsList, FieldsValues
        ' End If

    End With
    ' poniższe niepotrzebne tylko do testowania
    Call TestListRS(objRs:=Rst, objWrk:=ThisWorkbook.Worksheets("test"))

WriteIntoExcel_Exit:
    On Error Resume Next
    If Not Rst Is Nothing Then
        With Rst
            If .State = adStateOpen Then .Close
        End With
        Set Rst = Nothing
    End If
    If Not Cn Is Nothing Then
        With Cn
            If .State = adStateOpen Then .Close
        End With
        Set Cn = Nothing
    End If
    Exit Sub

WriteIntoExcel_Error:
    MsgBox "Błąd : ( " & Err.Number & " ) " & Err.Description & vbCrLf & _
           "Procedura : " & "WriteIntoExcel", vbExclamation
    Resume WriteIntoExcel_Exit
End Sub

Public Sub TestListRS(objRs As ADODB.Recordset, objWrk As Worksheet)
' niepotrzebne tylko do testowania
Dim i As Long
Dim j As Long

    With objWrk
        .Activate
        .Cells.Clear
    End With
    j = 1
    With objRs
        For i = 0 To .Fields.Count - 1
            objWrk.Cells(1, i + 2) = .Fields(i).Name & " : " & .Fields(i).DefinedSize
        Next
        If Not (.BOF And .BOF) Then
            .MoveFirst
            Do While Not .EOF
                j = j + 1
                objWrk.Cells(j, 1) = j - 1
                For i = 0 To .Fields.Count - 1
                    objWrk.Cells(j, i + 2) = .Fields(i).Value & ""
                Next
                .MoveNext
            Loop
        End If
    End With
End Sub


----------------------------------------------------------------
Aby uniezależnić się od reszty arkusza, można przy czystym arkuszu zdefiniować:
moja_nazwa=Arkusz1!$A$1:$D$1
Wówczas formatowanie jak widzę nie przeszkadza, lecz rozszerzanie nazwy przy dodawaniu rekordów ma miejsc przy ADODB (2.6), a przy na przykład linkowanym arkusz w ACC , już nie.
Zatem nie jest to jednoznaczna sprawa, ponieważ nie wiadomo, kto kiedy i jak doda te rekordy.
napisał: WojMak
postów: 7


umieszczony:
24 sierpnia 2007
17:47

  
Witam,

Pisałęm szybko i może trochę chaotycznie. Otóż, w pliku new.xls w pierwszym wierszu w komórkach od A1 do A4 umieściłęm 4 nazwy tj Pole1, Pole2,Pole3,Pole4 bo bez nich mój zestaw rekordów miał tylko jedno pole, nie mogłem dodawać wartości w polach innych niż 0. Domniemam, że nie ustawiłem jakiejś właściwości przy łączeniu ale mniejsza o to.
Oczywiście oczekiwałem dodania danych tak, jak do tabeli ale niestety efekt był inny i dlatego zwróciłem się o pomoc na forum. Oba pliki umieściłem tutaj: http://chomikuj.pl/Default.aspx?logout=WojMak

Może i opis stoi w sprzeczności z kodem ale rzeczywistość jest inna.

Pozdrawiam

Wojciech
napisał: jalamas
postów: 316


umieszczony:
24 sierpnia 2007
03:23

  
Z Twojej procedury wynika, iż w skoroszycie w arkuszu Arkusz1 powinny być:
- w 1-szym wierszu powinny nazwy 4 pól tabeli bazy danych, jakkolwiek by one się nie nazywały, powinny być to rożne nazwy w zasadzie.
Metoda Addnew dodaje nowy rekord do tabeli, nie jakieś tam "nie pierwsze wolne", tak jak do tabeli bazy danych.

Twój opis natomiast pozostaje w sprzeczności z tym kodem... pola A1 : A4 ????
Zatem nie wiem co mam o tym sądzić.
napisał: WojMak
postów: 7


umieszczony:
23 sierpnia 2007
17:58

  
Witam,

Zamieszczam przykładową procedurę jaką chciałem wykorzystać do zapisywania danych w arkuszu Excel'a bez otwierania go i z pomocą przyszło ADO.

Urychomienie poniższej procedury:

Public Sub WriteIntoExcel()
    Dim cn As ADODB.Connection, rst As New ADODB.Recordset, strQuery As String _
    FieldsList As Variant, FieldsValues As Variant
    
    FieldsList = Array(0, 1, 2, 3)
    FieldsValues = Array("wpis1", "wpis2", "wpis3", "wpis4")
    
    Set cn = New ADODB.Connection

    With cn
        .Provider = "Microsoft.Jet.OLEDB.4.0"
        .ConnectionString = "Data Source=C:\new.xls;" & _
                            "Extended Properties=Excel 8.0;"
        .Open
    End With

    strQuery = "SELECT * FROM [Arkusz1$]"

    rst.Open strQuery, cn, adOpenDynamic, adLockOptimistic

    With rst
        .AddNew FieldsList, FieldsValues
        .Update
    End With

    rst.Close
    Set rst = Nothing

End Sub



której celem jest zapisanie danych do pliku C:\new.xls, w którym komórki z zakresu A1 do A4 nazwałem Pole1, Poe2 itd jest wstawienie danych ale nie od pierwszego wolnego wiersza ale od wiersza trzeciego, a co ciekwasze po usunięciu wartości, zapisaniu pliku i ponownym uruchomieniu procedury wartości są dodawane w taki sposób jakby Excel "pamiętał" poprzednie zajęte wiersze. dlaczego tak się dzieje? Czy można to jakoś wyeliminować?

Pozdrawiam

Wojciech


<-wstecz  1  dalej->
wszystkich stron: 1


Sortuj posty: z