Discussion:
[VBA] multiselect listbox - usuwanie zaznaczonych pozycji.
(Wiadomość utworzona zbyt dawno temu. Odpowiedź niemożliwa.)
Marcin Ziemian
2006-03-24 07:37:53 UTC
Permalink
Witam.

Googlałem, googlałem i nic nie wygooglałem sensownego :/

Mam stworzony na formularzu Accessowym (mdb) listbox z opcją extended
multiselect. Do tego mam niezwiązane pole tekstowe i 2 przyciski, które mają
za zadanie wstawiać i usuwać pozycje z listy.

Wstawianie - no problem, bo wstawiam pojedynczo wartość pola tekstowego.
Natomiast chciałbym umożliwić użytkownikom możliwość usuwania grupowo
zaznaczonych w listbox-ie pozycji.

Problem tkwi w tym, że przy usunięciu jakiejś pozycji zmienia się indeksacja
pozycji, które były zaznaczone, a zaznaczenie zostaje wyzerowane (w sumie
jest to dość logiczne, choć denerwujące z punktu widzenia usuwania
pozycji ;)).

W pocie czoła wysmażyłem coś takiego:

Private Sub Polecenie56_Click()
ilosc = Me.Lista51.ItemsSelected.Count
If ilosc > 1 Then
indeksy = ""
For Each varItm In Me.Lista51.ItemsSelected
indeksy = indeksy & " " & CStr(varItm)
Next varItm
indeksy = Split(Trim(indeksy), " ", , vbTextCompare)
For i = 0 To ilosc - 1
Me.Lista51.RemoveItem CInt(indeksy(i))
'Korekcja indeksow w zwiazku ze zmiana liczby elementow
'listbox-a
For j = i + 1 To ilosc - 1
indeksy(j) = CStr(CInt(indeksy(j)) - 1)
Next j
Next i
Else
Me.Lista51.RemoveItem Me.Lista51.ItemsSelected
End If
End Sub

Jest to dość chyba zakręcone i nie wiem, czy na dłuższą metę będzie się
sprawdzać, więc moje pytanie brzmi: czy można prościej i skuteczniej?

Z góry dzięki za wszelkie odpowiedzi

Pozdro
--
M.Z.
--
Wysłano z serwisu Usenet w portalu Gazeta.pl -> http://www.gazeta.pl/usenet/
Medyk
2006-03-24 09:17:59 UTC
Permalink
Post by Marcin Ziemian
Witam.
Googlałem, googlałem i nic nie wygooglałem sensownego :/
Mam stworzony na formularzu Accessowym (mdb) listbox z opcją extended
multiselect. Do tego mam niezwiązane pole tekstowe i 2 przyciski, które mają
za zadanie wstawiać i usuwać pozycje z listy.
Wstawianie - no problem, bo wstawiam pojedynczo wartość pola tekstowego.
Natomiast chciałbym umożliwić użytkownikom możliwość usuwania grupowo
zaznaczonych w listbox-ie pozycji.
Problem tkwi w tym, że przy usunięciu jakiejś pozycji zmienia się indeksacja
pozycji, które były zaznaczone, a zaznaczenie zostaje wyzerowane (w sumie
jest to dość logiczne, choć denerwujące z punktu widzenia usuwania
pozycji ;)).
Private Sub Polecenie56_Click()
ilosc = Me.Lista51.ItemsSelected.Count
If ilosc > 1 Then
indeksy = ""
For Each varItm In Me.Lista51.ItemsSelected
indeksy = indeksy & " " & CStr(varItm)
Next varItm
indeksy = Split(Trim(indeksy), " ", , vbTextCompare)
For i = 0 To ilosc - 1
Me.Lista51.RemoveItem CInt(indeksy(i))
'Korekcja indeksow w zwiazku ze zmiana liczby elementow
'listbox-a
For j = i + 1 To ilosc - 1
indeksy(j) = CStr(CInt(indeksy(j)) - 1)
Next j
Next i
Else
Me.Lista51.RemoveItem Me.Lista51.ItemsSelected
End If
End Sub
Jest to dość chyba zakręcone i nie wiem, czy na dłuższą metę będzie się
sprawdzać, więc moje pytanie brzmi: czy można prościej i skuteczniej?
----------------------------

Na przyklad tak:

Dim itm As Variant
Dim conn As ADODB.Connection
Set conn = CurrentProject.Connection

For Each itm In Me.lboxTwojaLista.ItemsSelected
strSQL = "DELETE * FROM TwojaTabela WHERE Identyfikator = "
conn.Execute (strSQL & Me.lboxDane.Column(0, itm))
Next itm

conn.Close
Set conn = Nothing

Pozdrawiam:
Medyk
--
============= P o l N E W S ==============
archiwum i przeszukiwanie newsów
http://www.polnews.pl
Marcin Ziemian
2006-03-24 11:09:55 UTC
Permalink
Post by Medyk
Dim itm As Variant
Dim conn As ADODB.Connection
Set conn = CurrentProject.Connection
For Each itm In Me.lboxTwojaLista.ItemsSelected
strSQL = "DELETE * FROM TwojaTabela WHERE Identyfikator = "
conn.Execute (strSQL & Me.lboxDane.Column(0, itm))
Next itm
conn.Close
Set conn = Nothing
Ha, oczywiście zapomniałem dopisać, że listbox jest niezwiązany, a
wykorzystuję z niej RowSource do kreowania zapisu w polu tekstowym ;)
Stąd raczej nie wyda aktualizacja tabel ;)

Poczytam jeszcze sobie to, co podesłał KP.

Dzięx i pozdro!
--
M.Z.
--
Wysłano z serwisu Usenet w portalu Gazeta.pl -> http://www.gazeta.pl/usenet/
Medyk
2006-03-24 12:14:12 UTC
Permalink
|Ha, oczywiście zapomniałem dopisać, że listbox jest niezwiązany...

W takim razie co jest zrodlem wierszy listboxa?
Zauwaz,
ze kontrolka ta ma dwie wlasciwosci - 'Zrodlo formantu' i 'Zrodlo wierszy'
--
============= P o l N E W S ==============
archiwum i przeszukiwanie newsów
http://www.polnews.pl
Marcin Ziemian
2006-03-24 12:45:33 UTC
Permalink
Post by Medyk
W takim razie co jest zrodlem wierszy listboxa?
Zauwaz,
ze kontrolka ta ma dwie wlasciwosci - 'Zrodlo formantu' i 'Zrodlo wierszy'
Lista wartości sporządzana w kodzie VB w trakcie zdarzenia OnCurrent
formularza na podstawie wartości z ukrytego pola tekstowego związanego z
polem tekstowym.
Pewnie mógłbym przejechać tekst w tym polu tekstowym i zrobić Replace() wg
wartości pozycji dla Listbox.ItemsSelected, ale potem musiałbym się biedzić z
szukaniem podwójnych separatorów, itd, więc wolę się bawić na niezwiązanym
listbox-ie, niż grzebać w tabelach, zwłaszcza, że takie grzebanie uzależnione
by było od jakości połączenia z zapleczem, a zabawa z listbox-em to tylko
robótka w międzymordziu, zatem lokalnie ;) Poza tym w razie zerwania
połączenia dane zostają bez zmian w tabeli.

Chociaż nie wiem - może faktycznie zabieram się do tego od d[a-z]{2}y strony

Pozdro :)
--
M.Z.
--
Wysłano z serwisu Usenet w portalu Gazeta.pl -> http://www.gazeta.pl/usenet/
Piotr Lipski
2006-03-24 13:11:03 UTC
Permalink
On Fri, 24 Mar 2006 12:45:33 +0000 (UTC), Marcin Ziemian wrote:

[...]
Post by Marcin Ziemian
Chociaż nie wiem - może faktycznie zabieram się do tego od d[a-z]{2}y strony
[...]

Sugeruję użyć zapisu "d[p-u]{2}y" - wygląda bardziej dupowato.
Albo nawet "d[up][up]y" (wersja dla jąkałów...)

:-)
--
PL, co słowa-klucze wyłapuje bezbłędnie niezależnie od zasadniczej treści
posta...
Nguyen Bang Giang
2006-03-25 06:24:57 UTC
Permalink
Post by Marcin Ziemian
Pewnie mógłbym przejechać tekst w tym polu tekstowym i zrobić Replace() wg
wartości pozycji dla Listbox.ItemsSelected, ale potem musiałbym się biedzić z
szukaniem podwójnych separatorów, itd,
Jeśli dodajesz na końcu RowSource dodatkowy separator, robisz Replace() wg
(ItemsSelected & Separtaor) to nie będziesz musiał się biedzić z podwójnymi
separatorami.
Post by Marcin Ziemian
więc wolę się bawić na niezwiązanym
listbox-ie, niż grzebać w tabelach, zwłaszcza, że takie grzebanie uzależnione
by było od jakości połączenia z zapleczem, a zabawa z listbox-em to tylko
robótka w międzymordziu, zatem lokalnie ;) Poza tym w razie zerwania
połączenia dane zostają bez zmian w tabeli.
To, że operujesz RowSource nie ma nic wspólnego z tym czy listbox jest
związany czy nie. Źródłem listboxu może być i lista wartości przechowana w
frontedzie jako jakaś właściwość, ...

Pozdrawiam.
Marcin Ziemian
2006-03-25 19:22:00 UTC
Permalink
Post by Nguyen Bang Giang
Jeśli dodajesz na końcu RowSource dodatkowy separator, robisz Replace() wg
(ItemsSelected & Separtaor) to nie będziesz musiał się biedzić z podwójnymi
separatorami.
Hmm... Jakiś pomysł to jest, choć tak jak pisałem wcześniej, wolę dla
bezpieczeństwa pobawić się RowSourcem niezwiązanego listbox-a ;)
Post by Nguyen Bang Giang
To, że operujesz RowSource nie ma nic wspólnego z tym czy listbox jest
związany czy nie. Źródłem listboxu może być i lista wartości przechowana w
frontedzie jako jakaś właściwość, ...
Wiem, że można tam wstawić wszystko, co tylko spełnia kryteria
kolekcyjności, ale to nie zmienia niczego w moim podejściu do sprawy, bo ja
potrzebuję schować w pewnym polu dane tekstowe.
Problem mój polega na tym, że próbuję stworzyć pewną aplikację, w której są
rejestrowane sprawy (administracja), które w efekcie przeprowadzanych
kontroli mogą wykazać zbieżność z innymi (jedną, kilkoma, kilkunastoma,
itd). I gdzieś te informacje chciałbym schować i żeby nie tworzyć klikuset
dodatkowych pól w rekordzie trzymam to w jednym polu w postaci ciągu
wartości oddzielanych średnikiem, dzięki czemu mam możliwość bardzo
szybkiego przetworzenia tej informacji do celów wizualnych :)
Jeśli coś robię źle, to piszcie ;)

Pozdro
--
M.Z.
--
Wysłano z serwisu Usenet w portalu Gazeta.pl -> http://www.gazeta.pl/usenet/
Krzysztof Naworyta
2006-03-31 16:46:37 UTC
Permalink
Juzer Marcin Ziemian <***@gazeta.pl> napisał

| Wiem, że można tam wstawić wszystko, co tylko spełnia kryteria
| kolekcyjności, ale to nie zmienia niczego w moim podejściu do sprawy,
| bo ja potrzebuję schować w pewnym polu dane tekstowe.
| Problem mój polega na tym, że próbuję stworzyć pewną aplikację, w
| której są rejestrowane sprawy (administracja), które w efekcie
| przeprowadzanych kontroli mogą wykazać zbieżność z innymi (jedną,
| kilkoma, kilkunastoma, itd). I gdzieś te informacje chciałbym schować i
| żeby nie tworzyć klikuset dodatkowych pól w rekordzie trzymam to w
| jednym polu w postaci ciągu wartości oddzielanych średnikiem, dzięki
| czemu mam możliwość bardzo szybkiego przetworzenia tej informacji do
| celów wizualnych :)

coś mnie się widzi, że można to przetwarzać znacznie szybciej, gdyby
zastosować podtabelę ;-)
ale rób co chcesz ...

| Jeśli coś robię źle, to piszcie ;)

np:

Private Sub Command0_Click()
Dim c As New Collection
Dim i As Integer

With Me.Lista0
For i = 0 To .ListCount - 1
If .Selected(i) Then
c.Add CVar(i)
End If
Next
For i = c.Count To 1 Step -1
.RemoveItem c.Item(i)
Next
End With

End Sub
--
KN
(MVP, M$ Office Access)

archiwum grupy:
http://groups.google.pl/advanced_group_search
(grupa: pl*msaccess)
Marcin Ziemian
2006-04-03 07:15:39 UTC
Permalink
Post by Krzysztof Naworyta
coś mnie się widzi, że można to przetwarzać znacznie szybciej, gdyby
zastosować podtabelę ;-)
ale rób co chcesz ...
Czyli co... Kolekcja robi tu za podtabelę? Tak mam traktować zapis poniżej?
Post by Krzysztof Naworyta
Private Sub Command0_Click()
Dim c As New Collection
Dim i As Integer
With Me.Lista0
For i = 0 To .ListCount - 1
If .Selected(i) Then
c.Add CVar(i)
End If
Next
For i = c.Count To 1 Step -1
.RemoveItem c.Item(i)
Next
End With
End Sub
Bo jeśli tak, to przekonałeś mnie ;) Działa świetnie. Dzięki :)

Pozdro!
--
M.Z.
--
Wysłano z serwisu Usenet w portalu Gazeta.pl -> http://www.gazeta.pl/usenet/
Krzysztof Naworyta
2006-04-03 09:08:13 UTC
Permalink
Marcin Ziemian <***@gazeta.pl> napisał:

|| coś mnie się widzi, że można to przetwarzać znacznie szybciej, gdyby
|| zastosować podtabelę ;-)
|| ale rób co chcesz ...
|
| Czyli co... Kolekcja robi tu za podtabelę? Tak mam traktować zapis
| poniżej?

Nie, procedura, którą podałem po prostu robi to co chciałeś, przy bieżących
założeniach.

A podtabela (zamiast pola z listą elementów) pozwalałaby na zupełnie inne
wyszukiwania.
W tej chwili aby znaleźć określoną encję, która w tym polu ma m.in.
"AlaMaKota" musisz dokonać zwykłego skanowania po rekordach.
Nie pomoże żaden indeks (tym bardziej, że pewnie jest to pole memo?)

Oczywiście jeśli informacje zawarte w tym polu służą jedynie do
"wizualizacji" i nigdy po nich nie będziesz niczego szukał, to podejście z
średnikami jest ok. ;-)

--
KN
Marcin Ziemian
2006-04-03 13:12:47 UTC
Permalink
Post by Krzysztof Naworyta
Nie, procedura, którą podałem po prostu robi to co chciałeś, przy bieżących
założeniach.
Uhum... No w każdym razie działa jak należy :) I o to mi chodziło, wobec
czego jeszcze raz dzięki :)
Post by Krzysztof Naworyta
A podtabela (zamiast pola z listą elementów) pozwalałaby na zupełnie inne
wyszukiwania.
Uhum... No na szczęście (przynajmniej dla mnie i mojego czasu) nie mam
potrzeby szukania wg tego pola.
Post by Krzysztof Naworyta
(tym bardziej, że pewnie jest to pole memo?)
Owszem.
Post by Krzysztof Naworyta
Oczywiście jeśli informacje zawarte w tym polu służą jedynie do
"wizualizacji" i nigdy po nich nie będziesz niczego szukał, to podejście z
średnikami jest ok. ;-)
Przynajmniej na razie nie mam takiej potrzeby. Dane te wykorzystywane są do
bieżącego przetwożenia informacji i aktualizacji danych (w tym polu trzymam
indentyfikatory kolidujących rekordów, które powinny zmienić swój status, co
jest realizowane w procedurze zapisu rekordu z niezerowym polem "sprawy w
kolizji").

Cóż, myślę, że to jest EOT.

Pozdro zatem i do zczytania w innych wątkach :)
--
M.Z.
--
Wysłano z serwisu Usenet w portalu Gazeta.pl -> http://www.gazeta.pl/usenet/
Krzysztof Pozorek
2006-03-24 09:42:51 UTC
Permalink
(...)
Post by Marcin Ziemian
Wstawianie - no problem, bo wstawiam pojedynczo wartość pola tekstowego.
Natomiast chciałbym umożliwić użytkownikom możliwość usuwania grupowo
zaznaczonych w listbox-ie pozycji.
Problem tkwi w tym, że przy usunięciu jakiejś pozycji zmienia się indeksacja
pozycji, które były zaznaczone, a zaznaczenie zostaje wyzerowane (w sumie
jest to dość logiczne, choć denerwujące z punktu widzenia usuwania
pozycji ;)).
Moze przyda Ci sie jakis konkretny przyklad obslugi list multiselect:
http://www.access.vis.pl/war233.htm

K.P.
Loading...