Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Import danych z SQL przez VBA

813 views
Skip to first unread message

maciej_kd

unread,
May 18, 2010, 4:53:01 AM5/18/10
to
Witam!
Mój problem wygląda następująco: Chcę pobrać z tabeli SQL jeden rekord. W
VBA musze okreslić np. Destination:=Range("B1"). Dane zwracane są w wierszu.
Proszę o informację, czy istnieje możliwość, aby dane zwracane były nie w
wierszu, ale w kolumnie?

Makro wygląda nastepująco:

Sub odczyt_SQL_doTabl()
connstring = "ODBC;DSN=Nazwa;UID=User;PWD=Password;Database=NazwaBazy"
sqlstring = "select * from TABELA where Nr_Rekordu='" & InputBox("podaj nr
rekordu") & "'"
With ActiveSheet.QueryTables.Add(Connection:=connstring, _
Destination:=Range("B1"), Sql:=sqlstring)
.Refresh BackgroundQuery:=False
.ResultRange.Select
End With
End Sub

Daniel Stawicki

unread,
May 18, 2010, 10:58:15 AM5/18/10
to
A jakie to są dane zwracane, może podaj jakiś przykład.
Ale generalnie dane to tablica, czyli w pionie a nie poziomie.

--
Pozdrawiam
Daniel Stawicki

Specjalista ds. Pomocy Technicznej

Pomoc Techniczna Microsoft

http://support.microsoft.com

// Uprzejmie proszę o nie wysyłanie zapytań bezpośrednio na mój adres email.
Zapytania takie pozostaną bez odpowiedzi, gdyż adres ten nie jest
monitorowany. //

IDKrzych

unread,
May 18, 2010, 4:36:03 PM5/18/10
to

Tak jak P.Daniel niedokładnie rozumiem problem ....

Mogę tylko domyślać się, że pobierasz z bazy JEDEN rekord z wieloma polami
("kolumnami") ... i chcesz dane każdego pola wypisać jedno pod drugim (w
układzie pionowym)
Takie rozwiązanie należy do raczej niestandardowych i nie wykonasz tego
chyba w ten sposób.
Wg. mnie powinieneś pobrać recordset w kodzie i sterować jego
"wyświetleniem" ... mniej więcej tak:

Dim moCon As New ADODB.Connection
Dim rsDat As New ADODB.Recordset
Dim sSQL As String

moCon.ConnectionString =
"ODBC;DSN=Nazwa;UID=User;PWD=Password;Database=NazwaBazy;"
moCon.Open

sSQL = "select * from TABELA where Nr_Rekordu='" & InputBox("podaj nr
rekordu") & "'"
rsDat.Open sSQL, moCon, adOpenStatic, adLockReadOnly, adCmdText

If Not rsDat.EOF Then
For lwiersz = 0 To rsDat.Fields.Count -1
With Sheet1.Range("A1")
.Offset(lwiersz, 0).Value = rsDat.Fields(lwiersz ).Name
.Offset(lwiersz, 1).Value = rsDat.Fields(lwiersz ).Value
End With
Next lwiersz
End If

Na szybko wypisałem kod, więc mam nadzieje, że ewentualne literówki itp.
poprawisz ;)
Idea powinna być czytelna.
Pozdrawiam
--
IDKrzych

"Jakkolwiek będzie - będzie inaczej, aniżeli sobie wyobrażamy
- ponieważ między Dobrem a Złem znajdujemy się w życiu i w świecie
wielowymiarowym,
w którym dokumentnie pomieszane jest Przypadkowe z Nieuchronnym."
(S. Lem 1999)

maciej_kd

unread,
May 19, 2010, 2:59:01 AM5/19/10
to

"IDKrzych" wrote:

> .
>
Dziękuje bardzo za reakcję w mojej sprawie.
Dokładnie tak. Jak napisałeś. Chcę pobrac jeden rekord z tablicy z wieloma
kolumnami (posiadającymi różne typy danych - liczbowe, tekstowe, data...) i
chcę wypisać je jedno pod drugim (w kolumnie)....

Skopiowałem przykład do swojego makra w Excelu i już wysypuje się na
początku zwracając błąd: Compile Error: User-defined type not defined

Sprawdziłem problem wpisując wszystko z ręki i po "Dim moCon As New" w oknie
wyboru nie mam ADODB...

Daniel Stawicki

unread,
May 19, 2010, 5:25:52 AM5/19/10
to
Dam ci bardzo prosty przykład


Po pierwsze musisz dodac referencje (w edytorze VBA Tools References) do
Microsoft ActiveX Object 2.8 Library

A dalej

Dim oConn As Object (polaczenie z sql)
DIm rs As ADODB.Recordset (zmienna przechowujaca wynik z sql)
Dim oRS As Object
dim sSQL as string (zmienna przechowujaca polecenie SQL)

oConn.Open = "Provider=SQLOLEDB.1;Persist Security Info=True;User ID=NAZWA
UZYTKOWNIKA SQL ;Initial Catalog=NAZWA BAZY;Data Source=NAZWA SERWERA;Use
Procedure for Prepare=1;Auto Translate=True;Packet Size=4096;Password=HASLO"
(otwiera polaczenie)

sSQL = "Tutaj wpisz swojego selecta)

Set rs = oConn.Execute(sSQL) (pobranie danych z SQL)

Arkusz1.Cells(1, 1).Value = rs.Fields(0).Value
Arkusz1.Cells(1, 2).Value = rs.Fields(1).Value
Arkusz1.Cells(1, 3).Value = rs.Fields(2).Value

Do While Not rs.EOF

Petli w sumie mozesz sie pozbyc w twoim przypadku.
A dane z SQL masz w rs.fields i numerek. 0 to pierwsza kolumna, 1 to druga
kolumna itd.

rs.MoveNext
Loop

IDKrzych

unread,
May 19, 2010, 5:27:32 AM5/19/10
to
> Dziękuje bardzo za reakcję w mojej sprawie.
> Dokładnie tak. Jak napisałeś. Chcę pobrac jeden rekord z tablicy z wieloma
> kolumnami (posiadającymi różne typy danych - liczbowe, tekstowe, data...)
> i
> chcę wypisać je jedno pod drugim (w kolumnie)....
>
> Skopiowałem przykład do swojego makra w Excelu i już wysypuje się na
> początku zwracając błąd: Compile Error: User-defined type not defined
>
> Sprawdziłem problem wpisując wszystko z ręki i po "Dim moCon As New" w
> oknie
> wyboru nie mam ADODB...
>

Aha tak .. zapomniałem napisać:
Potrzebna jest zdefiniowana referencja do biblioteki wykorzystującej ADO
Musisz w oknie Visual Basic .. menu Tools > References .. tu znalezć na
liście "Microsoft ActiveX Data Objects 2.8 Library
" i "zaptaszyć" :) ... (wszystko będąc/widząc arkusz/moduł makra w którym
jest używane ADODB)

maciej_kd

unread,
May 19, 2010, 7:03:01 AM5/19/10
to
Dzięki za wyjaśnienie. Małymi kroczkami poruszam się do przodu…
Napotkałem jednak na kolejny błąd. Wysypuje się na moCon.Open zwracając błąd:
Run-time terror ‘-2147467259 (80004005)’: [Microsoft][Menedżer sterowników
ODBC] Nie można odnaleźć nazwy źródła danych, a nie ma podanego sterownika
domyślnego

Nie wiem w czym tkwi problem, gdyż pierwotne makro na połączeniu wskazanym
na początku postu działało.

maciej_kd

unread,
May 19, 2010, 7:07:01 AM5/19/10
to
Dzięki za podpowiedź. Sprawdzam równolegle wszystkie rozwiązania.
Zaproponowane przez Ciebie wysypuje się na oConn.Open. Zwraca mi następujący
błąd:
Run-time terror ‘91’: Object variable or With block variable not set


IDKrzych

unread,
May 19, 2010, 9:38:13 AM5/19/10
to

to już ciężko będzie, bez podania konkretniejszych informacji ... sam w
sumie mało korzystam z ODBC (to już prawie wymarły standard):
problemem jest ciąg połączenia .. tu podałem ten z Twojego przykładu:


"ODBC;DSN=Nazwa;UID=User;PWD=Password;Database=NazwaBazy"

musisz skonfigurować sterownik ODBC i plik wymiany DSN.

z jakiego typu bazy danych pobierasz rekordy ?
musisz wygooglować odpowiedni ciąg ... czasami troszkę metodą prób i błędów
dobrać
(pomocna stronka http://www.connectionstrings.com/)

najlepij poprzez ADO ...
np dla plików Accessa *.mdb "provider" w najprostszej formie wystarczy np.
tak:

"Provider='Microsoft.Jet.OLEDB.4.0';Data Source='d:\pliki\baza.mdb';"

(Microsoft.Jet też już jest niewspierany, ale ze względu na popularność
jeszcze chyba długo posłuży w większości windowsów)

maciej_kd

unread,
May 21, 2010, 6:07:01 AM5/21/10
to
Panowie!
Wielkie dzięki za pomoc. Obie Wasze propozycje są świetne. Jeszcze nei wiem,
z którego skorzystam, ale i tak ogromne podziękowania dla Was - generalny
kierunek dziąłań z Waszej strony był idealny.
Na początku miałem problemy z błędami, jednak udało mi sie je rozwiązać. I
tak:
Rozwiązanie P. IDKrzych zmodyfikowałem w wierszu moConString do postaci:

"Provider=SQLOLEDB.1;UID=UserName;PWD=Password;" & _
"Persist Security Info=False;" & _
"Initial Catalog=NazwaBazy;" & _
"Data Source=Nazwa"

Natomiast w rozwiązaniu P. Daniela zmienie uległa deklaracja zmiennej

Dim oConn As New ADODB.Connection

oraz w dalszej części

oConn.ConnectionString = "Provider=SQLOLEDB.1;UID=UserName;PWD=Password;" & _
"Persist Security Info=False;" & _
"Initial Catalog=NazwaBazy;" & _
"Data Source=Nazwa"
oConn.Open

Tak, czy tak, jeszcze raz podziękowania za pomoc i pełen profesjonalizm.
pozdrawiam,

IDKrzych

unread,
May 21, 2010, 7:05:14 AM5/21/10
to
> Wielkie dzięki za pomoc. Obie Wasze propozycje są świetne. Jeszcze nei
> wiem,
> z którego skorzystam, ale i tak ogromne podziękowania dla Was - generalny
> kierunek dziąłań z Waszej strony był idealny.
> Na początku miałem problemy z błędami, jednak udało mi sie je rozwiązać. I
> tak:

Cieszę się że mogliśmy pomóc :)


> Natomiast w rozwiązaniu P. Daniela zmienie uległa deklaracja zmiennej
>
> Dim oConn As New ADODB.Connection

na marginesie:
deklaracji "as Object" jak było w pierwotnym przykładzie należy się
wystrzegać .... jest to tak zwane "późne wiązanie" i wiąże się z
pogorszeniem wydajności i trudnościami podczas pisania "brak podpowiedzi w
edytorze".
Wszystkie obiekty należy od początku deklarować jako konkretne ... a
przypadki "as object" tylko w szczególnych wypadkach gdy musimy do jednej
zmiennej podawać referencje do różnych obiektów.

0 new messages