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ł: 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
|
|