napisał: asterix postów: 16
umieszczony: 6 maja 2008 21:54
|
|
Cytat: Może spróbuj tak:
Function imagepath() As String
imagepath = "d:\tmp\"
End Function
niestety pojawia się błąd 481 |
|
napisał: Harry postów: 42
umieszczony: 6 maja 2008 12:28
|
|
Może spróbuj tak:
Function imagepath() As String
imagepath = "d:\tmp\"
End Function |
|
napisał: asterix postów: 16
umieszczony: 4 maja 2008 18:24
|
|
okej uporałem się z tym, wina lezała po mojej stronie, stworzyłem sobie wszystko od nowa na spokojenie i zaczeło działać(robione wszystko bardzo podobnie niż wcześniej) wielkie dzięki
dopasowalem sobie wszystko oczywiście do swoich potrzeb
mam tylko jeden problem a mianowicie zastosowałaś funkcję imagepath() jednak nie wiem co tam ma się kryć pod nią:(
wynik jest taki że nie pobiera z bazy rysunku (wiem że na ogół nie zaleca sie umieszczania rysunków w bazie tylko odnośnikow na dysk, ale ja mam swój powód - baza będzie przenoszona na różne komputery nie podpiete do sieci, a chce zaoszczędzić przenoszenia multum plików za każdym razem więc z tąd mój wybór taki a nie inny)
komentując komentując linijke z imagepath() oczywiście pojawia się błąd 3001 o argumentach niewłaściwego typu, co jest naturalne bo nie ma jak sie odwołać do rys bo nie wie gdzie
spróbowałem w taki sposób
funkcja imagepath()
dim dir as string
dim = "d:\tmp\"
end function
daje bląd 481 invalid picture
do katalogu nie ma ograniczeń dostępu dla nikogo jeżeli chodzi o odczyt i zapis
jeżeli można prosił bym o pomoc |
|
napisał: jalamas postów: 316
umieszczony: 6 kwietnia 2008 17:28
|
|
Cytat: nie pokazywane czy to w combobox czy w listbox
1. Nie rozumiem, co ma być pokazywane combobox czy w listbox
2. Nie znam takiego numeru błędu "nie działa" ... tym bardziej, że nie wiem jak zaadptowałeś moje procedury... a patrząc na Twoje posty mam wątpliwości... sorry.
Mam wrażenie, że jest to "łapanie się prawą ręką za lewe ucho"... raz sys... raz inny duperszwanc... sorry.
3. Tak naprawdę z Twojego opisu nie wiem, co chcesz, mimo wszelkich wysiłków, nie rozumiem i raczej trudno mi napisać coś, co będzie działało zawsze wszędzie, jestem blondynką..
Więc albo wysil się i dokładnie opisz, co masz, albo dołącz swoją aplikację.
kropkompl... |
|
napisał: asterix postów: 16
umieszczony: 6 kwietnia 2008 14:04
edytowany: 6 kwietnia 2008 14:14
|
|
niestety to rozwiązanie nie działa, próbowałem również na prostrze sposoby i gdzie inndziej podpowiadane i dalej lipa:(
dane ładnie są zbierane ale już nie pokazywane czy to w combobox czy w listbox
nie mam pomysłu dlaczego :(
a używam ado msado28 |
|
napisał: jalamas postów: 316
umieszczony: 27 marca 2008 07:03
|
|
Nie wiem, dlaczego z tablicy. Jeżeli typy można dać do tablicy o tyle obiekty raczej bym nie dała do tablicy.
Poniższy cytat z pomocy Excela narzuca ograniczenia.
Cytat:Setting ColumnCount to -1 displays all the available columns.
For an unbound data source, there is a 10-column limit (0 to 9).
I to trzeba mieć na uwadze !
Oraz typy pól... gdzie niegdzie... Skoro jednak dajesz sobie radę z typami, pominęłam...
O ile tabela zawierająca typy (tbltypy) załóżmy, ma 3 pola, a opis typu nie wymaga pola memo,
bo do opisania typu wystarczy tylko np. 200 znaków, to tabela zawierająca obiekty (tblobiekty)
jest nieco bardziej, przypuszczam, skomplikowana Może memo, czy Image.
Ponadto, ja bym nie przechowywała obrazków w tabeli, to nie jest dobra praktyka, a jedynie ścieżki.
Lecz wspomniałeś, pokazałam przykład.
Na wspomnianym przykładzie 2-ch tabel: tbltypy i tblobiekty.
Przykładowo niech będzie:
tbltypy
- id_typob - klucz podstawowy, auto
- nazwa_typob - klucz unikalny
- opis_typob
tblobiekty
- id_ob - klucz podstawowy, auto
- nazwa_ob - klucz unikalny
- id_typob - klucz obcy
- opis_ob
- Image_ob
Niech będzie dalej zupełnie symbolicznie:
Cytat:CREATE TABLE [dbo].[tbltypy] (
[id_typob] int IDENTITY(1, 1) NOT NULL,
[nazwa_typob] varchar(20) COLLATE Polish_CI_AS NOT NULL,
[opis_typob] varchar(50) COLLATE Polish_CI_AS NULL,
PRIMARY KEY CLUSTERED ([id_typob]),
UNIQUE ([nazwa_typob])
)
ON [PRIMARY]
CREATE TABLE [dbo].[tblobiekty] (
[id_ob] int IDENTITY(1, 1) NOT NULL,
[nazwa_ob] varchar(20) COLLATE Polish_CI_AS NOT NULL,
[id_typob] int NOT NULL,
[opis_ob] varchar(20) COLLATE Polish_CI_AS NULL,
[Image_ob] image NULL,
PRIMARY KEY CLUSTERED ([id_ob]),
UNIQUE ([nazwa_ob]),
CONSTRAINT [tblobiekty_fk] FOREIGN KEY ([id_typob])
REFERENCES [dbo].[tbltypy] ([id_typob])
ON UPDATE NO ACTION
ON DELETE NO ACTION
)
ON [PRIMARY]
TEXTIMAGE_ON [PRIMARY]
Moim zdaniem wynik zapytania do tabeli typów (tbltypy) wystarczy trzymać w ComboBox.
(id_typob, nazwa_typob, opis_typob)
Ponieważ ComboBox w "stanie zwiniętym" ma widoczną tylko jedną kolumnę:
- chowamy szerokością 1-szą kolumnę
- 2-gą widać (nazwa typu)
- na przykład opis pokazujemy w kontrolce Label (Caption) po Click w ComboBox
zatem, Recordset tabeli typów można śmiało zamknąć po wypełnieniu kontrolki
Tabela przechowująca obiekty natomiast (tblobiekty):
- wynik zapytania trzymałabym w Recordsecie zadeklarowanym w sekcji General kodu klasy UserForm.
- do kontrolki ListBox ładowałabym tylko niezbędne kolumny (id_ob, nazwa_ob)
- kolumnę z id_ob ukryła
- przy czym wykorzystałabym tutaj tzw. Disconnected Recordset - Clon Recordset po rozłączeniu (disconnect)
Czyli, po pobraniu wyniku zapytania ActiveConnection tego Recordset ustawiła na Nothing,
potem Clone oryginał i połączenie z bazą zamknęłabym.
Po wybraniu typu w kontrolce ComboBox zawierającej typy filtrowałabym clon Recordsetu obiektów
i GetRows do ListBox , ale tylko istotne pola (id_ob, nazwa_ob).
Po wybraniu pozycji z ListBox obiektów Find (tu też można byłoby po Clonie)
I teraz odpowiednie pola Recordsetu do kontrolek.
Tu na przykładzie string SQL żeby było widać, jakie View, powinny być w bazie, a jak piszesz resztę umiesz,
ORDER BY pominęłam tymczasem, ale 3ba
ComboBox: cmbTyp - typy
- ColumnCount -- > 3
- BoundColumn -- > 1
- ColumnWidths -- > "0" -1-sza na 0 szer. widoczna nazwa typu
- Style -- > fmStyleDropDownList
ListBox lstOb - obiekty
- ColumnCount -- > 2
- BoundColumn -- > 1
- ColumnWidths -- > "0" -1-sza na 0 szer. widoczna nazwa obiektu
- MultiSelect -- > fmMultiSelectSingle
Nie jest to żadne standardowe rozwiązanie, a jedynie bardzo uproszczona forma,
ponieważ w istocie wszystko zależy zarówno od celu jak i od ilości danych.
Mam nadzieję, że się nie pomyliłam.
Nie wiem, którą wersję ADO masz... wykorzystujesz wczesne wiązanie ?
'----------------------------------------------------------
' Form Class : frmObiektyTypy
'----------------------------------------------------------
Option Explicit
Dim RsOb As ADODB.Recordset
Dim bRsReady As Boolean
Dim bObSelRsReady As Boolean
Private Sub UserForm_Initialize()
Call PobierzRsDisconnected
End Sub
' xxxxx adodb error
Public Sub PobierzRsDisconnected()
On Error GoTo Pobie_Error
Dim strSql As String
Dim Cn As ADODB.Connection
Dim RsTemp As ADODB.Recordset
Set Cn = New ADODB.Connection
With Cn
.ConnectionString = MojConnString()
.CursorLocation = adUseClient
.Open
End With
' Typy
strSql = "SELECT id_typob,nazwa_typob,opis_typob FROM tbltypy"
Set RsTemp = Cn.Execute(strSql, , adCmdText)
With RsTemp
Set .ActiveConnection = Nothing ' Disconnect
If Not (.BOF And .EOF) Then
Me.cmbTyp.Column() = .GetRows(adGetRowsRest, adBookmarkFirst) ' do ComboBox
End If
.Close ' nie jest juz potrzebny
End With
' Obiekty
strSql = "SELECT id_ob, nazwa_ob,opis_ob, id_typob,Image_ob FROM tblobiekty"
Set RsTemp = New ADODB.Recordset
With RsTemp
.CursorLocation = adUseClient: .LockType = adLockReadOnly: .CursorType = adOpenStatic
.Open strSql, Cn
Set .ActiveConnection = Nothing ' Disconnect
Set RsOb = New ADODB.Recordset
Set RsOb = .Clone
.Close
End With
bRsReady = True
With Me.cmbTyp
If .ListCount > 0 Then .ListIndex = 0
End With
Pobie_Exit:
On Error Resume Next
Call CloseAnyRs(RsTemp)
Call CloseAnyConnection(Cn) 'bo polaczenie nie juz ptrzebne
Exit Sub
Pobie_Error:
Call CloseAnyRs(RsOb) ' gdyby byl blad zamykam rowniez ten RS
MsgBox "Błąd : ( " & Err.Number & " ) " & Err.Description & vbCrLf & _
"Procedura : " & "Pobie", vbExclamation
Resume Pobie_Exit
End Sub
Private Sub RefreshObjList()
On Error GoTo RefreObjList_Error
' filtrujemy na na clonie tymczasowym tylko do pobrania danych
bObSelRsReady = False
Dim RsClone As ADODB.Recordset
With Me
If .cmbTyp.ListIndex < 0 Then Exit Sub
.ImageOb.Picture = LoadPicture("")
.lblopis_typob.Caption = Me.cmbTyp.Column(2)
.lstOb.Clear
.lblOPisOb.Caption = ""
End With
If RsOb Is Nothing Then Exit Sub
With RsOb
If .State <> adStateOpen Then Exit Sub
If (.EOF And .BOF) Then Exit Sub
End With
Set RsClone = RsOb.Clone(adLockReadOnly)
With RsClone ' filtr na Clonie
.Filter = "id_typob=" & CStr(Me.cmbTyp.Value)
If Not (.EOF And .BOF) Then
' tylko 2 pola do ListBox
Me.lstOb.Column() = .GetRows(adGetRowsRest, adBookmarkFirst, VBA.Array("id_ob", "nazwa_ob"))
End If
End With
bObSelRsReady = True
With Me.lstOb
If .ListCount > 0 Then .ListIndex = 0
End With
RefreObjList_Exit:
On Error Resume Next
Call CloseAnyRs(RsClone) '2-gi clon musze zamknac zwolinic pamiec
Exit Sub
RefreObjList_Error:
MsgBox "Błąd : ( " & Err.Number & " ) " & Err.Description & vbCrLf & _
"Procedura : " & "RefreObjList", vbExclamation
Resume RefreObjList_Exit
End Sub
Private Sub cmbTyp_Click()
If bRsReady = True Then RefreshObjList
End Sub
Private Sub lstOb_Click()
If bObSelRsReady = False Then Exit Sub
Dim strIdOb As String
With Me
.ImageOb.Picture = LoadPicture("")
.lblOPisOb.Caption = ""
End With
With lstOb
If .ListIndex < 0 Then Exit Sub
strIdOb = CStr(.Value)
End With
If RsOb Is Nothing Then Exit Sub
With RsOb ' w zasadzie tu tez mozna po Clone
If .State <> adStateOpen Then Exit Sub
If (.EOF And .BOF) Then Exit Sub
.Find "id_ob=" & strIdOb, , adSearchForward, adBookmarkFirst ' to jest po unikalnym id_ob
If .EOF Then Exit Sub
If Not IsNull(.Fields("opis_ob").Value) Then Me.lblOPisOb.Caption = .Fields("opis_ob").Value
Call ImageToFile(.Fields("Image_ob"), Me.ImageOb)
End With
End Sub
Private Sub UserForm_Terminate()
Call CloseAnyRs(RsOb)
End Sub
'------ to moze byc w standard jesli jest gdzies jeszcze potrzebne -----------
Public Sub ImageToFile(Fld As ADODB.Field, CtlImage As MSForms.Image)
On Error GoTo ImageToFile_Error
If IsNull(Fld.Value) Then Exit Sub
Dim strTmp As String
Dim oStream As ADODB.Stream
strTmp = ImagePath() & "Temp.bmp"
Set oStream = New ADODB.Stream
With oStream
.Type = adTypeBinary
.Open
.Write Fld.Value
.SaveToFile strTmp, adSaveCreateOverWrite
End With
CtlImage.Picture = LoadPicture(strTmp) ' do Image Control
ImageToFile_Exit:
On Error Resume Next
Kill (strTmp) ' przed kill 3ba sprawdzic czy jest ...
Call CloseAnyStream(oStream)
Exit Sub
ImageToFile_Error:
MsgBox "Błąd : ( " & Err.Number & " ) " & Err.Description & vbCrLf & _
"Procedura : " & "ImageToFile", vbExclamation
Resume ImageToFile_Exit
End Sub
Public Sub CloseAnyStream(objStream As ADODB.Stream)
On Error Resume Next
If Not objStream Is Nothing Then
With objStream
If .State = adStateOpen Then
.Close
End If
End With
End If
Set objStream = Nothing
End Sub
Public Sub CloseAnyRs(oRs As ADODB.Recordset)
On Error Resume Next
If Not oRs Is Nothing Then
With oRs
If .State = adStateOpen Then .Close
End With
End If
Set oRs = Nothing
End Sub
Public Sub CloseAnyConnection(oConn As ADODB.Connection)
On Error Resume Next
If Not oConn Is Nothing Then
With oConn
If .State = adStateOpen Then .Close
End With
End If
Set oConn = Nothing
End Sub |
|
napisał: asterix postów: 16
umieszczony: 25 marca 2008 20:53
|
|
Cytat: Ja natomiast prosiłabym, zanim coś napiszę o dokładne sprecyzowanie problemu,
opisowo, bo nie do końca rozumiem co chcesz zrobić, bądź ustosunkowanie się do
poniższych punktów
- umiesz czy nie umiesz zaprojektować widok i procedurę składową
- masz na formie kontrolkę ComboBox
- w niej chcesz mieć listę tabel znajdujących się w Twojej bazie danych
- masz też na formie kontrolkę ListBox
- w zależności od wybranej w kontrolce ComboBox nazwy tabeli
- chcesz widzieć w kontrolce LisBox nazwy pól tej tabeli oraz ich typy i co jeszcze?
- czy masz zupełnie inne pytania
Uprawnienia itd... na serwerze pomijam...
?
- w bazie potrafie i mam porobione widoki i procedury
- za pomocą poniższego kodu wywołuję sobie procedure i parametrami jakimi potrzebuję, bądź też lekko zmodyfikowana wersja, że istnieje możliwość wywołania po przez select... (to też już mam)
- dane są przechowywane w formie tablicy arrWynik (także działa)
- problem mam taki aby dane z tejże tablicy przenieść na kontrolkę listBox, comboBox
- przez dane rozumię np dana1;koło,kwadrat... nie interesują mnie jakiego typu są dane bo to już odpowiednio sobię potrafię obsłuzyć
- ciekawiła by mnie także opcja aby po wybraniu z combobox danych A wyświetlały się dane B w listBox
- rozumiem że podobnie się ma sprawa z pokazywaniem odpowiedniego rys w kontrolce Image czy też danych w kontrolce Frame
- przykład dotyczacy wywołania procedury poniżej wziąłem tylko jako przykład, dane i tabele jak ich obsługa są w rzeczywistości inne
no ale dla przykładu tabela1: id, nazwa_obj, typ_obj_ref, opis, image tabela:2 id_typ, nazwa_typ, opis
do tego prosta procedura wywolująca z jakimś tam parametrem lub widok w zależności od potrzeb
przykładowo w combobox np była by lista typów a w listbox nazwy, w kontrolce image rysunek a w frame opis dla poszczególnej nazwy (czyli bawienie się odpowiednimi zależnościami pomiedzy kontrolkami)
co do uprawnień poustawiałem je odpowiednio dla danego użytkownika i tutaj nie mam najmniejszego problemu(baza działa tak jak chce:) ) |
|
napisał: jalamas postów: 316
umieszczony: 25 marca 2008 08:40
edytowany: 25 marca 2008 08:41
|
|
Ja natomiast prosiłabym, zanim coś napiszę o dokładne sprecyzowanie problemu,
opisowo, bo nie do końca rozumiem co chcesz zrobić, bądź ustosunkowanie się do
poniższych punktów
- umiesz czy nie umiesz zaprojektować widok i procedurę składową
- masz na formie kontrolkę ComboBox
- w niej chcesz mieć listę tabel znajdujących się w Twojej bazie danych
- masz też na formie kontrolkę ListBox
- w zależności od wybranej w kontrolce ComboBox nazwy tabeli
- chcesz widzieć w kontrolce LisBox nazwy pól tej tabeli oraz ich typy i co jeszcze?
- czy masz zupełnie inne pytania
Uprawnienia itd... na serwerze pomijam...
? |
|
napisał: asterix postów: 16
umieszczony: 23 marca 2008 23:28
|
|
sorki że post pod postem, pls o pomoc, dzięki z gory |
|
napisał: jalamas postów: 316
umieszczony: 10 marca 2008 12:24
edytowany: 10 marca 2008 12:25
|
|
Cytat: jednak to jest troche mało praktyczne ponieważ trzeba wywołać lancz_db przed każdą operacją na bazie
To zależy co i kiedy robisz. Pozwolę sobie dać taki przykład nie związany z bazą danych.
Magazyn, wnosimy wynosimy towary, ciężkie drzwi, skomplikowane otwarcie, zabezpieczenia itd...
Jeśli czynności te wykonujemy na przykład, co 12 godz. raczej bez sensu jest trzymać cały czas otwarte drzwi zwłaszcza, gdy nie ma dostatecznego dozoru.
Lecz gdy co np. 10 minut...
Po prostu należy ocenić sytuację i stworzyć sobie plan działania.
O położeniu kursora zacznij tutaj:
http://blogs.msdn.com/selvar/archive/2007/11/11/ado-cursors.aspx
Przeczytaj też linki na dole.
Cytat:jak najlepiej budować pod vba polecenia sql (insert,update,select,delete)
Nie mogę się doczytać jakie to środowisko VBA Access czy Excel?
Jeżeli masz Access, to w okienku bazy danych/Pomoc/Spis treści jest punkt "Materiały na temat języka Jet SQL"
Nie to dokładnie to, co trzeba, lecz jest po polsku i może poczytaj.
Ale lepiej tutaj:
http://www.centrumxp.pl/dotNET/21,1,kategoria,Kurs_SQL.aspx
Oraz zainteresuj się adp w ACC.
Poza tym deklaracji na poziomie sekcji General tak jak w przytoczonym kodzie
Cytat:Dim lacz As New ADODB.Connection
Dim Rs As New ADODB.Recordset
Dim sSql As String
wobec umieszczonego w procedurze:
Cytat:Set lacz = Nothing
też nie bardzo ma sens...
Skoro koniecznie chcesz zamknąć i otworzyć połączenie w procedurze zmienna lokalna wystarczy
( a tylko Set lacz = Nothing nie jest poprawnym zamknięciem) ...
Połączenia tutaj:
http://www.carlprothman.net/Default.aspx?tabid=81
OLE DB Data Providers
Można wykorzystać MZTools Add-in (do Office) do budowy ciągu połączenia.
Może, bo nie wiem, co masz, ściągnij sobie:
http://www.download3000.com/download_8365.html
Przykładowo:
Sub PobierzPrzechCmdParam()
' procedura - tresc z parametrem - nazwa ProcPolaTabeli
'CREATE PROCEDURE ProcPolaTabeli
'@Table_Name varchar(128)
'AS
'BEGIN
' SELECT *
' FROM SYSCOLUMNS
' WHERE (ID=object_id(@Table_Name))
'End
On Error GoTo Pobie_Error
Dim arrWynik
Dim lngRow As Long
Dim lngCol As Long
'----------
Dim Cn As ADODB.Connection
Set Cn = New ADODB.Connection
With Cn
.ConnectionString = MojConnString()
.CursorLocation = adUseClient
.Open
End With
Call PolaTabeliParamProc(Cn, "tblmoja", arrWynik)
If IsArray(arrWynik) Then
For lngRow = 0 To UBound(arrWynik, 2)
For lngCol = 0 To UBound(arrWynik, 1)
' do okienka Immediate
Debug.Print arrWynik(lngCol, lngRow)
Next
Next
End If
Pobie_Exit:
On Error Resume Next
If Not Cn Is Nothing Then
With Cn
If .State = adStateOpen Then .Close
End With
End If
Set Cn = Nothing
Exit Sub
Pobie_Error:
MsgBox "Błąd : ( " & Err.Number & " ) " & Err.Description & vbCrLf & _
"Procedura : " & "Pobie", vbExclamation
Resume Pobie_Exit
End Sub
'-------------------------------------------
Sub PolaTabeliParamProc(oCn As ADODB.Connection, ByVal sTableName As String, vWynik)
On Error GoTo PolaTabel_Error
Dim strProcName As String
strProcName = "ProcPolaTabeli"
Dim lngRecordsAffected As Long
Dim Rs As ADODB.Recordset
Dim Cmd As ADODB.Command
Set Rs = New ADODB.Recordset
Set Cmd = New ADODB.Command
With Cmd
Set .ActiveConnection = oCn
.CommandText = strProcName
.CommandType = adCmdStoredProc
' niektore sposoby
' tak:
' Set Rs = Cmd.Execute(lngRecordsAffected, "[" & sTableName & "]", adCmdStoredProc)
' lub tak
' Set Rs = .Execute(, VBA.Array("[" & sTableName & "]"))
' lub tak
.Parameters.Append .CreateParameter("Table_Name", _
adVarChar, adParamInput, _
128, "[" & sTableName & "]")
Set Rs = .Execute(lngRecordsAffected)
End With
With Rs
If Not (.EOF And .BOF) Then
vWynik = .GetRows(adGetRowsRest, adBookmarkFirst, .Fields("name").Name)
End If
End With
PolaTabel_Exit:
On Error Resume Next
If Not Rs Is Nothing Then
With Rs
If .State = adStateOpen Then .Close
End With
End If
Set Rs = Nothing
Set Cmd = Nothing
Exit Sub
PolaTabel_Error:
MsgBox "Błąd : ( " & Err.Number & " ) " & Err.Description & vbCrLf & _
"Procedura : " & "PolaTabel", vbExclamation
Resume PolaTabel_Exit
End Sub Tylko nie bardzo wiem, po co Ci na tym poziomie wiedzy akurat taka procedura.
Może zacznij od procedury z parametrem zwracającej Recordset, na przykład listę osób o wybranym nazwisku. |
|
napisał: asterix postów: 16
umieszczony: 9 marca 2008 02:11
|
|
kurcze wielkie dzięki, teraz zupełnie inaczej muszę spojrzeć na sprawy łączenia się z bazą oraz operacje na niej
samo głupie łączenie się robiłem zupełnie w inny sposób, który mnie z leksza denerwował ale cuż działał
muszę sobie poczytać conieco więcej o ado
co do procedur w bazie to będe je robił, póki co zaczynam dopiero zabawę więc sprawdzam krok po kroku jak co działa
samo połączenie ja miałem zorganizowane w taki sposób:
Option Explicit
Dim lacz As New ADODB.Connection
Dim Rs As New ADODB.Recordset
Dim sSql As String
Sub lancz_db()
Dim sDbMSSQLconn As String
Dim lDbState As Long
On Error GoTo Error_Handling
sDbMSSQLconn = "Provider=sqloledb;Data Source=***\SQL***;Initial Catalog=***;Uid=***;Pwd=***;"
'łączenie z bazą
lacz.Open sDbMSSQLconn
lDbState = lacz.State
'MsgBox "połączono z bazą"
Debug.Print lacz
sSql = "use [baza]"
Rs.Open sSql, lacz 'wykonanie zapytania
ExitHere:
' lacz.Close
Rs.Close
Set lacz = Nothing
' Set rs = Nothing
Exit Sub
Error_Handling:
'jeżeli urzytkownik da cancel.
If Err.Number = 91 Then
Resume ExitHere
End If
End Sub
jednak to jest troche mało praktyczne ponieważ trzeba wywołać lancz_db przed każdą operacją na bazie
Idąć jednak dalej w temat, jak najlepiej budować pod vba polecenia sql (insert,update,select,delete) tak aby móc stworzone procedury wykorzystywać uniwersalnie wg potrzeb, nie chcę gotowego rozwiązania tylko podpowiedź z czego kozystać, wkońcu trzeba się jakoś nauczyć:)
Znalazłem gdzieś takie rozwiązanie aby skożystać z procedur składowanych już po stronie serwera bazy w taki sposób(rozwiązanie napisane w c#)
cmdSQL.CommandType = CommandType.StoredProcedure;
cmdSQL.Parameters.Add("@nazwa", SqlDbType.nchar);
cmdSQL.ExecuteNonQuery();
wydaje mi się ono dobre, tylko teraz jak pod vba by to wyglądało?
mam jeszcze takie pytanie odnośnie .CursorLocation = adUseClient - na czym to polega, jak sobie podejrzałem co on wprowadza pod to ukazało mi się 3, ale nie wiem jak to interpretować
Dzięki za pomoc |
|
napisał: jalamas postów: 316
umieszczony: 8 marca 2008 19:17
|
|
Nie bardzo rozumiem Twoje pytanie... więc może na początek tak:
Sub Pobierz()
On Error GoTo Pobie_Error
Dim arrWynik
Dim lngRow As Long
Dim lngCol As Long
Dim Cn As ADODB.Connection
Set Cn = New ADODB.Connection
With Cn
.ConnectionString = MojConnString()
.CursorLocation = adUseClient
.Open
End With
Call PolaTabeli(Cn, "tblmoja", arrWynik)
If IsArray(arrWynik) Then
For lngRow = 0 To UBound(arrWynik, 2)
For lngCol = 0 To UBound(arrWynik, 1)
' do okienka Immediate
Debug.Print arrWynik(lngCol, lngRow)
Next
Next
End If
Pobie_Exit:
On Error Resume Next
If Not Cn Is Nothing Then
With Cn
If .State = adStateOpen Then .Close
End With
End If
Set Cn = Nothing
Exit Sub
Pobie_Error:
MsgBox "Błąd : ( " & Err.Number & " ) " & Err.Description & vbCrLf & _
"Procedura : " & "Pobie", vbExclamation
Resume Pobie_Exit
End Sub
'--------------------------
Sub PolaTabeli(oCn As ADODB.Connection, ByVal sTableName As String, vWynik)
On Error GoTo PolaTabel_Error
Dim strSql As String
strSql = "SELECT name FROM SYSCOLUMNS WHERE ID=object_id('[" & sTableName & "]')"
Dim Rs As ADODB.Recordset
Set Rs = New ADODB.Recordset
With Rs
Set .ActiveConnection = oCn
.CursorLocation = adUseClient
.Open strSql
If Not (.EOF And .BOF) Then
vWynik = .GetRows(adGetRowsRest, adBookmarkFirst, .Fields(0).Name)
End If
End With
PolaTabel_Exit:
On Error Resume Next
If Not Rs Is Nothing Then
With Rs
If .State = adStateOpen Then .Close
End With
End If
Set Rs = Nothing
Exit Sub
PolaTabel_Error:
MsgBox "Błąd : ( " & Err.Number & " ) " & Err.Description & vbCrLf & _
"Procedura : " & "PolaTabel", vbExclamation
Resume PolaTabel_Exit
End Sub Aczkolwiek technicznie poprawnie i bezpieczniej byłoby stworzyć procedurę składową z parametrem w bazie danych, a nie taki sql string... |
|
napisał: asterix postów: 16
umieszczony: 8 marca 2008 00:34
|
|
mam taki problem że nie wiem jak przekazać dane do funkcji aby prawidłowo z niej można było wyciągnąć dane najlepiej stablicowane
póki co mam coś takiego
Sub ISelct()
lancz_db
'''fiSelectSql ("[test]")
Dim kolumny(1 To 10) As String
'''''tutaj chcę przypisać nazwy kolumn pobranych po przez poniższą funkcję''''''
''''' np żeby to dzialało w taki sp kolumny(1) = fiSelectSql(1): kolumny(2) = fiSelectSql(2)
''''' lub po prostu potem to dać do pętli
'''' nie mam pomysu także jak dalej przekazać dane do zmiennej tabela
End Sub
'''' należalo by zmienić w jakiś sposób parametry wywołania
Function fiSelectSql(tabela As String) As String
Dim nazwy_kolumn As Collection
Set nazwy_kolumn = New Collection
' cmd.CommandText = "proc_" & tabela & "_select"
' cmd.CommandTimeout = 200
Dim sql As String
sql = "SELECT name FROM SYSCOLUMNS WHERE ID=object_id('" & tabela & "')"
rs.Open sql, lacz
While Not (rs.EOF)
nazwy_kolumn.Add (rs(0))
rs.MoveNext
Wend
Dim i, iCol As Integer
Dim kolumna(1 To 10) As String
iCol = nazwy_kolumn.Count
For i = 1 To iCol
kolumna(i) = nazwy_kolumn.Item(i)
Next i
rs.Close
lacz.Close
Set rs = Nothing
End Function |
|
wstecz 1 dalej wszystkich stron: 1
|
|