Czy mozna w jakis sposob przekazac kwerendzie zrobionej w kreatorze parametr
z kodu VB?
Mamy np akademicki przypadek Select... from... Where [podaj liczbe]
No i wlasnie czy mozna ja z kodu podac uruchamiajac kweende.
Wyobrazam to sobie np. tak: docmd.runsql MOjaKwerenda <parametry>.
Wiem, ze moge sobie cala kwerende uruchomic z kodu ale powyzsze trapi mnie
od jakiegos czasu.
Jezeli ktos zechce zaspokoic moja ciekawosc i odpowiedziec Tak(i podac ew.
skladnie) lub Nie to bede wdzieczny.
Pozdrawiam,
Krzysiek
| Czy mozna w jakis sposob przekazac kwerendzie zrobionej w kreatorze
| parametr z kodu VB?
|
| Mamy np akademicki przypadek Select... from... Where [podaj liczbe]
|
| No i wlasnie czy mozna ja z kodu podac uruchamiajac kweende.
|
| Wyobrazam to sobie np. tak: docmd.runsql MOjaKwerenda <parametry>.
RunSQL uruchamia jedynie funkcyjne wyrażenia SQL (update, delete, Insert
into), nie zwykłe "selecty".
Do otwarcia kwerendy wybierającej służy
DoCmd.OpenQuery() (zresztą dla funkcyjnych też)
Dlatego w "klasycznym" accessie nie ma możliwości podania z kodu
wymaganych parametrów.
Muszą one być wpisane do wyskakującego okienka.
Pewną, dość idiotyczną sztuczką jest przekazanie parametrów poprzez
SendKeys:
SendKeys "Ala ma kota~12~", 0
DoCmd.OpenQuery "MojaParametryczna"
Do pierwszego "okienka" poleci "Ala ma kota"
do drugiego: 12
Oczywiście powszechnie zamiast zwykłych parametrów stosuje się odwołania
do kontrolek formularza, skąd kwerenda sama pobierze wartości.
(ale myślę, że nie o to pytasz)
Całkiem spory sens mają _funkcyjne_ kwerendy parametryczne, bo je możemy
uruchomić nie tylko poprzez DoCmd.OpenQuery, ale także z poziomu ADO/DAO.
A tam mamy możliwość uprzedniego ustawienia wartości parametrów.
Kwerendy parametrycznej nie należy mylić z "Procedurą składowaną", bo
takiej w "klasycznym" accessie nie ma (są dostępne jedynie poprzez ADO,
jednak nie wiem czy ich wyniki da się wyświetlić w tradycyjnym gridzie)
--
KN
archiwum grupy:
http://groups.google.pl/advanced_group_search?&as_ugroup=pl*msaccess
Przeczytałem już odpowiedź KN, więc odpowiem dość ostrożnie... Można...
Dim Instrukcja as String, MojWarunek as Boolean
Instrukcja = DELETE * FROM Tabela WHERE ID = 1"
if MojWarunek = True Then
Instrukcja = Instrukcja & " OR ID = 5"
End If
DoCmd.RunSQL Instrukcja
Idąc dalej tym tropem można tak:
Dim Instrukcja as String, JakaWartosc as Variant
Instrukcja = DELETE * FROM Tabela WHERE ID = 1"
JakaWartosc = InputBox "Podaj ID: "
if not IsNull(JakaWartosc) Then
Instrukcja = Instrukcja & " OR ID = " & JakaWartosc
End If
DoCmd.RunSQL Instrukcja
Idąc jeszcze dalej możnaby spłodzić funkcyjkę UruchomEsKuElik(Instrucja
as String, Parametr as Variant) i wywoływać ją z kodu, tylko że po co?
Więcej zachodu z pisaniem funkcji niż "ręcznym" uruchamianiem instrukcji
SQL z kodu! Jakoś nie wyobrażam sobie uniwersalnej funkcji, która
rozwiąże każdy przypadek.
Poza tym, tak na marginesie, wciąż mi chodzi po głowie coś, co gdzieś
zaczytałem, że o wiele bardziej wydajnie jest pisać Query.Execute
zamiast Docmd.RunSQL :) .
Pozdrawiam,
Krzysiek
Zaraz zaraz, jeszcze jedna rzecz - przecież dla każdej kwerendy -
wybierającej także! - możesz w warunku (również w widoku projektu
kwerendy wybierającej) użyć odwolania do funkcji VBA...
= MojaFunkcja(Parametr)
Czyż nie?
Pozdrawiam,
Krzysiek
| Przeczytałem już odpowiedź KN, więc odpowiem dość ostrożnie... Można...
Ja pytanie potraktowałem literalnie
<cyte>
Wiem, ze moge sobie cala kwerende uruchomic z kodu, ale ...
</cyte>
A więc założyłem, że chłopakowi nie chodzi o tworzenie instrukcji SQL w
kodzie, ale chce obsłużyć juz istniejącą kwerendę.
| Poza tym, tak na marginesie, wciąż mi chodzi po głowie coś, co gdzieś
| zaczytałem, że o wiele bardziej wydajnie jest pisać Query.Execute
| zamiast Docmd.RunSQL :) .
Czy wiele bardziej wydajnie to nie wiem, testów nie robiłem ...
A)
Zarówno qr.execute czy DoCmd.RunSQL można ująć w ogólnej transakcji
(w przypadku RunSQL trzeba użyć drugiego parametru = True, zresztą
domyślnego)
B)
Zarówno qr.execute jak i RunSQL mogą uruchamiać kwerendy modyfikujące
strukturę:
ad1.
strSQL = "Alter Table Tabela1 Add Column x1 Text (20)"
Set db = OpenDatabase("C:\A\B\dane.mdb")
Set qr = db.CreateQueryDef("", strSQL)
qr.execute
czy po prostu:
db.execute strSQL
ad2.
strSQL = "Alter Table [;Database=C:\A\B\dane.mdb].[Tabela1] Add Column
x1 Text (20)"
DoCmd.RunSQL strSQL
(przyznam się, że dopiero dzisiaj doczytałem, że jest to możliwe poprzez
RunSQL !)
C)
Różnica objawia się właśnie w operowaniu na kwerendach parametrycznych -
już istniejących, np:
MojaKwerenda:
Update ... Set ...
Where pole1 = [podaj wartość]
Przy pomocy QueryDef wygląda to tak:
Set db = CurrentDb
Set qr = db.QueryDefs("MojaKwerenda")
qr.Parameters("podaj wartość") = "ABC"
'albo
'qr.Parameters(0) = "ABC"
qr.Execute
przy pomocy RunSQL tego nie zrealizujesz
tym bardziej nie zrealizujesz tego poprzez DoCmd.OpenQuery
Jasne, że można w kodzie raz dwa zdefiniować odpowiednie wyrażenie SQL,
wraz z podstawieniem parametru...
Co więcej - wyczytałem, że takie coś przejdzie przez optymalizator Jet'a,
zaś kwerenda parametryczna nie !
Niestety nie sprawdziłem tego, moze to plotka ...
D)
Dodatkowo obiekt/metoda DoCmd jest w accessie obwarowany wieloma
zastrzeżeniami.
Jego metody nie mogą być uruchamiane w bardzo róznych sytuacjach, np. w
funkcjach wywoływanych z poziomu pól wyrażeniowych. Metody DAO nie mają
tych ograniczeń.
E)
Pewien urok funkcji RunSQL polega na tym, że pokazuje postęp na pasku
zadań.
Tego z kolei nie mają metody DAO.
Dokladnie o to mi chodzi :-)
<ciach>
Bo wlasciwie to dalem zapytanie bo mam juz ktorys raz problem z tym, ze
czasem gdy robie kwerende a potem przenosze ja do kodu to niekoniecznie chce
mi od razu dzialac.
I wlasnie mam taki problem tez teraz. Zrobilem cos takiego z palca w
kwerendach i tam dziala:
INSERT INTO tblartykuly_oferty ( Id_Oferta, Id_Artykul, Ilosc, Opis )
SELECT (select top 1 max(IdOferta) from tblOferta where NumerOF = [Ostatni
numer oferty] and wersja = (select max (wersja) from tblOferta where
NumerOF = [Ostatni numer oferty])), [Id_Artykul], [Ilosc], [Opis]
FROM tblArtykuly_oferty
WHERE Id_Oferta=[ostatnie Id oferty];
Przenioslem to prawie doslownie do VBA i tak dziala:
DodajArtOfertySQL = "INSERT INTO tblartykuly_oferty ( Id_Oferta, Id_Artykul,
Ilosc, Opis) " & _
"SELECT (select top 1 max(IdOferta) from tblOferta where NumerOF = [Ostatni
numer oferty] and wersja = (select max (wersja) from tblOferta where
NumerOF = [Ostatni numer oferty])), [Id_Artykul], [Ilosc], [Opis]
" & _
"FROM tblArtykuly_oferty " & _
"WHERE Id_Oferta=" & intStareIDOferta & ";"
DoCmd.RunSQL DodajArtOfertySQL
Ale gdy chcialem juz przekazywac [ostatni numer oferty] jako zmienna to
pisze: Nieodpowiedni typ danych.
Zrobilem tak:
INSERT...
"SELECT (select top 1 max(IdOferta) from tblOferta where NumerOF = " &
intNrLastRecord & " and wersja = (select max (wersja) from tblOferta where
NumerOF = " & intNrLastRecord & ")), [Id_Artykul], [Ilosc], [Opis] " & _
itd.
Wydaje mi sie ze powinienem od select do [Id_artykul] wziac wszystko w "'"
ale wtedy krzyczy blad klucza.
No i gupi jestem :-|
Jesli bedzie sie chcialo ktoremus podpowiedziec to prosze bardzo, a jesli
nie to bede musial chyba zaimplementowac jedna z metod podanych powyzej.
Krzysiek
A pod zmienną intNrLastRecord masz na pewno prawidłową wartość? Zapisz
treść instrukcji SQL do zmiennej i zrób MsgBox Zmienna i będziesz
widział, w czym rzecz.
Dla mnie te podselecty nieco zawiłe, być może da się to oprogramować
jakimś prostym rekordsetem? Wiem, wiem, że mniej wydajnie, ale dla
jednego rekordu to żadne znaczenie.
Pozdrawiam,
Krzysiek
Dokladnie
> Zapisz treść instrukcji SQL do zmiennej i zrób MsgBox Zmienna i będziesz
> widział, w czym rzecz.
Robilem tak i nie wiem w czym tkwi blad
> Dla mnie te podselecty nieco zawiłe, być może da się to oprogramować
> jakimś prostym rekordsetem? Wiem, wiem, że mniej wydajnie, ale dla
> jednego rekordu to żadne znaczenie.
No juz tak tez kombinowalem, ale denerwuje mnie to ze ten SQL nie chce dzialac.
W ostatecznosci zrobie z tym Recordsetem
Krzysiek
--
Wysłano z serwisu OnetNiusy: http://niusy.onet.pl
Nie, tblOferta i tblArtykuly_oferty sa ze soba jak najbardziej powiazane przez
IDOferty.
> Nie mówię że na pewno mam rację - ale jeśli jej nie mam to wydaje się, że
> stuktura tabel jest porąbana (!), albo nie rozumiem co to zapytanie ma
> zwracać ...
TblArtykuly_oferty trzyma artykuly przyporzadkowane do danej oferty.
Ten SQL kopiuje zawartosc (czyli artykuly oferty) z jednej oferty do drugiej.
> Całośc dałoby się pewnie załatwić jedną kwerendą grupującą, co najwyżej z
> jednym podzapytaniem.
Hmm a co to kwerenda grupujaca?
> Odnośnie _doraźnej_ poprawy, zgaduję, że NumerOF jest polem tekstowym.
> Wtedy nie "cały select" leczy tylko miesce przypisania tego parametru (dwa
> miejsca) powinieneś "otoczyć" apostrofami:
Dokladnie. NumerOF to pole tekstowe. Sprawdze jak wroce do domu, ale moze
rzeczywiscie masz racje z tymi apostrofami
> Już o staranności w postach na Grupę nie wspomnę ...
Buuu... a tak sie staralem...
| Hmm a co to kwerenda grupujaca?
(lekcja geografii, 4-ta podstawówki)
- dziś powiemy jak naciągnąć prezerwatywę na globus.
- Psze Pana, a co to jest globus ???!!!
- no właśnie ! Od tego zaczniemy ...
:)))