detekcja QueryTable.Refresh - jak?
Piotr Lipski - 22-03-2007 00:07
detekcja QueryTable.Refresh - jak?
Mój kod "znakuje" każdy wiersz aruksza, wstawiając "X" w ostatniej kolumnie, w zdarzeniu Change.
Znacznik ten jest używany do późniejszego zapisania zmian w tabeli źródłowej.
Niestety przy odświeżaniu (right click -> refresh data) również jest generowane zdarzenie Worksheet_Change, w związku z czym świeżo odczytana tabela ma wszystkie rekordy oznaczone "X".
W jaki sposób (o ile się w ogóle da...) "sprytnie" sprawdzić w kodzie, że dane zdarzenie Change zostało wyzwolone przez QueryTable.Refresh a nie przez ręczną edycję?
-- PL
Piotr Lipski - 22-03-2007 00:07
On Wed, 21 Mar 2007 15:29:27 +0000, Piotr Lipski wrote:
[...] > W jaki sposób (o ile się w ogóle da...) "sprytnie" sprawdzić w kodzie, że > dane zdarzenie Change zostało wyzwolone przez QueryTable.Refresh a nie > przez ręczną edycję?
Póki co, sprawdzam Target.Count i jeżeli jest większe niż ileś-tam to przerywam znacznikowanie... Działa, ale chciałoby się eleganciej.
-- PL
pxd74 - 22-03-2007 00:07
Użytkownik "Piotr Lipski" <piotr.lipski@nie.p0czta.spamuj.bo.onet.w.ryj.pl > napisał w wiadomości news:xnlyr31k91ht.7wn068ls0yqw$.dlg@40tude.net... > Mój kod "znakuje" każdy wiersz aruksza, wstawiając "X" w ostatniej > kolumnie, w zdarzeniu Change. > > Znacznik ten jest używany do późniejszego zapisania zmian w tabeli > źródłowej. > > Niestety przy odświeżaniu (right click -> refresh data) również jest > generowane zdarzenie Worksheet_Change, w związku z czym świeżo odczytana > tabela ma wszystkie rekordy oznaczone "X". > > W jaki sposób (o ile się w ogóle da...) "sprytnie" sprawdzić w kodzie, że > dane zdarzenie Change zostało wyzwolone przez QueryTable.Refresh a nie > przez ręczną edycję?
Sprawdź właściwość Refreshing tej kwerendy (nie sprawdząłem czy to działa). Jak nie zadziała to pobaw się dodatkowo zdarzeniami AfterRefresh i BeforeRefresh obiektu QueryTables, np. przy pomocy zmiennej globalnej typu Boolean.
-- Pozdrowienia pxd74
janusz - 22-03-2007 00:07
Witam Użytkownik "Piotr Lipski" <piotr.lipski@nie.p0czta.spamuj.bo.onet.w.ryj.pl > napisał w wiadomości news:xnlyr31k91ht.7wn068ls0yqw$.dlg@40tude.net... > Mój kod "znakuje" każdy wiersz aruksza, wstawiając "X" w ostatniej > kolumnie, w zdarzeniu Change. > > Znacznik ten jest używany do późniejszego zapisania zmian w tabeli > źródłowej. > > Niestety przy odświeżaniu (right click -> refresh data) również jest > generowane zdarzenie Worksheet_Change, w związku z czym świeżo odczytana > tabela ma wszystkie rekordy oznaczone "X". > > W jaki sposób (o ile się w ogóle da...) "sprytnie" sprawdzić w kodzie, że > dane zdarzenie Change zostało wyzwolone przez QueryTable.Refresh a nie > przez ręczną edycję? >
Wlasna klasa dla Kwerendy
Public WithEvents MyQuery As QueryTable
Private Sub MyQuery _BeforeRefresh(Cancel As Boolean) Application.EnableEvents = False 'wylaczasz obsluge zdarzenie Change End Sub
Private Sub MyQuery _AfterRefresh(ByVal Success As Boolean) If Success Then Application.EnableEvents = True 'przywracasz obsluge zdarzenia Change End Sub
Janusz
Tajan - 22-03-2007 00:07
janusz wrote: > Witam > Użytkownik "Piotr Lipski" > <piotr.lipski@nie.p0czta.spamuj.bo.onet.w.ryj.pl > napisał w > wiadomości news:xnlyr31k91ht.7wn068ls0yqw$.dlg@40tude.net...
> Wlasna klasa dla Kwerendy > > Public WithEvents MyQuery As QueryTable > > Private Sub MyQuery _BeforeRefresh(Cancel As Boolean) > Application.EnableEvents = False > 'wylaczasz obsluge zdarzenie Change > End Sub > > Private Sub MyQuery _AfterRefresh(ByVal Success As Boolean) > If Success Then Application.EnableEvents = True > 'przywracasz obsluge zdarzenia Change > End Sub >
Hmm ... Dość ryzykowne to: "If Success Then Application.EnableEvents = True" :-) Jeżeli odświeżenie kwerendy z jakichś przyczyn nie powiedzie się, zostaniesz z wyłaczoną obsługą zdarzeń. Moim zdaniem, włączenie generowania zdarzeń powinno byc bezwarunkowe.
Tajan
janusz - 22-03-2007 00:07
Witam
> > Hmm ... Dość ryzykowne to: "If Success Then Application.EnableEvents = > True" :-) Jeżeli odświeżenie kwerendy z jakichś przyczyn nie powiedzie > się, zostaniesz z wyłaczoną obsługą zdarzeń. Moim zdaniem, włączenie > generowania zdarzeń powinno byc bezwarunkowe. > Oczywiscie blad powinno byc bez If-a niezaleznie czy kwerenda powiedzie sie czy nie po zakonczeniu dzialania kwerendy przywracamy obsluge Application.EnableEvents = True
Janusz
Piotr Lipski - 23-03-2007 00:03
On Wed, 21 Mar 2007 19:59:20 +0100, janusz wrote:
[...] > Wlasna klasa dla Kwerendy > > Public WithEvents MyQuery As QueryTable > > Private Sub MyQuery _BeforeRefresh(Cancel As Boolean) [...] > Private Sub MyQuery _AfterRefresh(ByVal Success As Boolean) [...]
No wygląda smakowicie, ale nie do końca rozumiem. Np. w którym miejscu tego kodu jest powiedziane o którą konkretnie QueryTable chodzi?
-- PL
pxd74 - 23-03-2007 00:03
janusz <b_janusz@op.pl> napisał(a):
> Private Sub MyQuery _AfterRefresh(ByVal Success As Boolean) > If Success Then Application.EnableEvents = True > 'przywracasz obsluge zdarzenia Change > End Sub
Zauważ. że ten kod jest bez sensu. Jeśli w zdarzeniu BeforeRefresh ustawisz Application.EnableEvents = False to zdarzenie AfterRefresh Ci się nie uruchomi podobnie jak wszystkie następne zdarzenia. Ogólnie mówiąc zawsze boję się używać Application.EnableEvents = False i staram się zawsze znaleźć inny sposób na wykonanie takich rzeczy - najpopularniejsza to zmienna globalna typu Boolean
-- Pozdrowienia pxd74
-- Wysłano z serwisu Usenet w portalu Gazeta.pl -> http://www.gazeta.pl/usenet/
pxd74 - 23-03-2007 00:03
Piotr Lipski <piotr.lipski@nie.p0czta.spamuj.bo.onet.w.ryj.pl > napisał(a):
> On Wed, 21 Mar 2007 19:59:20 +0100, janusz wrote: > > [...] > > Wlasna klasa dla Kwerendy > > > > Public WithEvents MyQuery As QueryTable > > > > Private Sub MyQuery _BeforeRefresh(Cancel As Boolean) > [...] > > Private Sub MyQuery _AfterRefresh(ByVal Success As Boolean) > [...] > > No wygląda smakowicie, ale nie do końca rozumiem. Np. w którym miejscu tego > kodu jest powiedziane o którą konkretnie QueryTable chodzi?
Poczytaj w helpie temat: "Using Events with the QueryTable Object" lub "Using Events with the Application Object".
Janusz nie napisał całego kodu. Ponieważ sprawadziłem co zwraca właściwość Refreshing w takim wypadku (zawsze False), to proponuje takie rozwiązanie:
'kod w module standardowym:
Public a As New Class1
'kod w module klasy o nazwie Class1:
Public WithEvents MyQuery As QueryTable Public czyOdświeżane As Boolean
Private Sub MyQuery_AfterRefresh(ByVal Success As Boolean) If Success Then czyOdświeżane = False End Sub
Private Sub MyQuery_BeforeRefresh(Cancel As Boolean) czyOdświeżane = True End Sub
'kod w module ThisWorkbook:
Private Sub Workbook_Open() Set a.MyQuery = Worksheets("Nazwa arkusza").QueryTables(1) End Sub
'kod w module arkusza:
Private Sub Worksheet_Change(ByVal Target As Range) If a.czyOdświeżane Then Exit Sub 'tu reszta kodu zdarzenia '... End Sub
-- Pozdrowienia pxd74
-- Wysłano z serwisu Usenet w portalu Gazeta.pl -> http://www.gazeta.pl/usenet/
janusz - 23-03-2007 00:03
Witam
> No wygląda smakowicie, ale nie do końca rozumiem. Np. w którym miejscu > tego > kodu jest powiedziane o którą konkretnie QueryTable chodzi? > Pewnie mozna jeszcze w inny sposob sprawdzic czy w target jest kwerenda lecz na teraz mam taki pomysl
Zaznacz obszar gdzie sa kwerendy i nadaj mu nazwe np ObszarKwerend i w BeforeRightClick sprawdzasz czy jest w zakresie " Intersect" gdzie sa kwerendy jezeli tak to odwolujesz sie do "Selection.QueryTable.Name"
Dim MyClass As New Class1
Private Sub Worksheet_BeforeRightClick(ByVal Target As Range, Cancel As Boolean)
If Not Intersect(Target, Range("ObszarKwerend")) Is Nothing Then Set MyClass.MyQuery = _ ThisWorkbook.Sheets(ActiveSheet.Name).QueryTables( Selection.QueryTable.Name) End If
End Sub
Janusz
janusz - 23-03-2007 00:03
Witam Użytkownik "pxd74" <pxd74.SKASUJ@gazeta.pl> napisał w wiadomości news:ettlei$phc$1@inews.gazeta.pl... > janusz <b_janusz@op.pl> napisał(a): > >> Private Sub MyQuery _AfterRefresh(ByVal Success As Boolean) >> If Success Then Application.EnableEvents = True >> 'przywracasz obsluge zdarzenia Change >> End Sub > > Zauważ. że ten kod jest bez sensu. Jeśli w zdarzeniu BeforeRefresh > ustawisz > Application.EnableEvents = False to zdarzenie AfterRefresh Ci się nie > uruchomi podobnie jak wszystkie następne zdarzenia. > Ogólnie mówiąc zawsze boję się używać Application.EnableEvents = False i > staram się zawsze znaleźć inny sposób na wykonanie takich rzeczy - > najpopularniejsza to zmienna globalna typu Boolean >
No tak chyba przesadzilem z tym EnableEvents ale jezeli uzyjesz tak jak pisal pxd74 czyOdświeżane typu Boolean
to reszta powinna dzialac bez problemu
Janusz
janusz - 23-03-2007 00:03
Witam Tak bedzie chyba poprawnie
Public WithEvents MyQuery As QueryTable
Private Sub MyQuery _BeforeRefresh(Cancel As Boolean) PracujeKwerenda = True End Sub
Private Sub MyQuery _AfterRefresh(ByVal Success As Boolean) PracujeKwerenda = False
End Sub
Dim MyClass As New Class1
Private Sub Worksheet_BeforeRightClick(ByVal Target As Range, Cancel As Boolean) If Not Intersect(Target, Range("ObszarKwerend")) Is Nothing Then Set MyClass.MyQuery = _ ThisWorkbook.Sheets(ActiveSheet.Name).QueryTables( Selection.QueryTable.Name) End If
End Sub
Private Sub Worksheet_Change(ByVal Target As Range) If PracujeKwerenda Then Exit Sub
End Sub
Chyba powinienem szybciej myslec a wolniej pisac
Janusz
zanotowane.pldoc.pisz.plpdf.pisz.pleffulla.pev.pl
|
Algorytm segmentacji w pracy inzynierskiej "Detekcja Twarzy w obrazach kolorowych"
Logo Polskiego Związku Łowieckiego Poszukiwane
[MySQL] dodawanie rekordow
[mysql] regularny autobackup bazy
Co do nauki Photoshopa?
przegladanie programu od strony zapytan SQL
[MSSQL] Rekurencja? Tabela, która tworzy drzewko
Biblia photoshopa
Oracle iSQL plus - historia zapytań
w czym projektujecie bazy ?
zanotowane.pldoc.pisz.plpdf.pisz.pltejsza.htw.pl
Cytat
Decede mihi sole - nie zasłaniaj mi słonca. Gdy kogoś kochasz, jesteś jak stworzyciel świata - na cokolwiek spojrzysz, nabiera to kształtu, wypełnia się barwą, światłem. Powietrze przytula się do ciebie, choćby był mróz, a ty masz w sobie tyle radości, że musisz ją rozdawać wokoło, bo się w tobie nie mieści Hoc fac - tak czyń. A tergo - od tyłu; z tyłu. I czarne włosy posiwieją. Safona |
|